diff options
author | bbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-04-21 22:54:32 +0000 |
---|---|---|
committer | bbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-04-21 22:54:32 +0000 |
commit | 878ddf1fc3540a715f63594ed22b6929e881afb4 (patch) | |
tree | c56c44dac138137b510e1fba7c3efe5e4d84bea2 /EdkModulePkg/Bus/Pci/PciBus | |
download | edk2-platforms-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.xz |
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Bus/Pci/PciBus')
36 files changed, 19995 insertions, 0 deletions
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c new file mode 100644 index 0000000000..ba7ec08c4e --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c @@ -0,0 +1,133 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "PciBus.h"
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {
+ PciBusComponentNameGetDriverName,
+ PciBusComponentNameGetControllerName,
+ "eng"
+};
+
+STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {
+ { "eng", (CHAR16 *) L"PCI Bus Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gPciBusComponentName.SupportedLanguages,
+ mPciBusDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language from the point of view of the driver specified
+ by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h new file mode 100644 index 0000000000..87d44c8427 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h @@ -0,0 +1,91 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.h
+
+Abstract:
+
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H
+#define _EFI_PCI_BUS_COMPONENT_NAME_H
+
+#ifndef EFI_SIZE_REDUCTION_APPLIED
+
+extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;
+
+#endif
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Language - TODO: add argument description
+ DriverName - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ControllerHandle - TODO: add argument description
+ ChildHandle - TODO: add argument description
+ Language - TODO: add argument description
+ ControllerName - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd new file mode 100644 index 0000000000..eea4971cbf --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>LightPciBusPciBus</BaseName>
+ <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:18</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>UefiDriverModelLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>EdkDxePrintLib</Library>
+ <Library>BaseLib</Library>
+ <Library>UefiDevicePathLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ </Libraries>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa new file mode 100644 index 0000000000..eec5c3c069 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>LightPciBusPciBus</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for LightPciBus module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:18</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>PciBus.h</Filename>
+ <Filename>PciIo.h</Filename>
+ <Filename>PciCommand.h</Filename>
+ <Filename>PciDeviceSupport.h</Filename>
+ <Filename>PciResourceSupport.h</Filename>
+ <Filename>PciEnumerator.h</Filename>
+ <Filename>PciEnumeratorSupport.h</Filename>
+ <Filename>PciOptionRomSupport.h</Filename>
+ <Filename>PciRomTable.h</Filename>
+ <Filename>PciLib.h</Filename>
+ <Filename>PciRomTable.c</Filename>
+ <Filename>PciDriverOverride.h</Filename>
+ <Filename>PciPowerManagement.h</Filename>
+ <Filename>PciPowerManagement.c</Filename>
+ <Filename>PciDriverOverride.c</Filename>
+ <Filename>PciOptionRomSupport.c</Filename>
+ <Filename>PciEnumerator.c</Filename>
+ <Filename>PciEnumeratorSupport.c</Filename>
+ <Filename>PciResourceSupport.c</Filename>
+ <Filename>PciCOmmand.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ <Filename>PciDeviceSupport.c</Filename>
+ <Filename>PciHotPlugSupport.c</Filename>
+ <Filename>PciBus.c</Filename>
+ <Filename>PciIo.c</Filename>
+ <Filename>LightPciLib.c</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciRootBridgeIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">UgaIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciPlatform</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">BusSpecificDriverOverride</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugRequest</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">IncompatiblePciDeviceSupport</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugInit</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHostBridgeResourceAllocation</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>
+ </Protocols>
+ <Guids>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>PciOptionRomTable</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>PciHotplugDevice</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>StatusCodeSpecificData</C_Name>
+ </GuidEntry>
+ </Guids>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <DriverBinding>gPciBusDriverBinding</DriverBinding>
+ <ComponentName>gPciBusComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c new file mode 100644 index 0000000000..28c8a794d4 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c @@ -0,0 +1,881 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ LightPciLib.c
+
+Abstract:
+
+ Light PCI Bus Driver Lib file
+ It abstracts some functions that can be different
+ between light PCI bus driver and full PCI bus driver
+
+Revision History
+
+--*/
+
+#include "pcibus.h"
+
+//
+// Light PCI bus driver woundn't support hotplug device
+// So just return
+//
+VOID
+InstallHotPlugRequestProtocol (
+ IN EFI_STATUS *Status
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Status - add argument and description to function comment
+{
+ return ;
+}
+
+//
+// Light PCI bus driver woundn't support hotplug device
+// So just skip install this GUID
+//
+VOID
+InstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+{
+ return ;
+}
+
+//
+// Light PCI bus driver woundn't support hotplug device
+// So just skip uninstall the GUID
+//
+VOID
+UninstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+{
+ return ;
+}
+
+//
+// Light PCI bus driver woundn't support PCCard
+// So it needn't get the bar of CardBus
+//
+VOID
+GetBackPcCardBar (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ return ;
+}
+
+//
+// Light PCI bus driver woundn't support resource reallocation
+// So just return
+//
+EFI_STATUS
+RemoveRejectedPciDevices (
+ EFI_HANDLE RootBridgeHandle,
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+ Bridge - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ return EFI_SUCCESS;
+}
+
+//
+// Light PCI bus driver woundn't support resource reallocation
+// Simplified the code
+//
+EFI_STATUS
+PciHostBridgeResourceAllocator (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_HANDLE RootBridgeHandle;
+ VOID *AcpiConfig;
+ EFI_STATUS Status;
+ UINT64 IoBase;
+ UINT64 Mem32Base;
+ UINT64 PMem32Base;
+ UINT64 Mem64Base;
+ UINT64 PMem64Base;
+ UINT64 MaxOptionRomSize;
+ PCI_RESOURCE_NODE *IoBridge;
+ PCI_RESOURCE_NODE *Mem32Bridge;
+ PCI_RESOURCE_NODE *PMem32Bridge;
+ PCI_RESOURCE_NODE *Mem64Bridge;
+ PCI_RESOURCE_NODE *PMem64Bridge;
+ PCI_RESOURCE_NODE IoPool;
+ PCI_RESOURCE_NODE Mem32Pool;
+ PCI_RESOURCE_NODE PMem32Pool;
+ PCI_RESOURCE_NODE Mem64Pool;
+ PCI_RESOURCE_NODE PMem64Pool;
+ REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+
+ //
+ // Initialize resource pool
+ //
+
+ InitializeResourcePool (&IoPool, PciBarTypeIo16);
+ InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);
+ InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);
+ InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);
+ InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);
+
+ RootBridgeDev = NULL;
+ RootBridgeHandle = 0;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get host bridge handle for status report
+ //
+ ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;
+
+ //
+ // Create the entire system resource map from the information collected by
+ // enumerator. Several resource tree was created
+ //
+
+ IoBridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFF,
+ 0,
+ PciBarTypeIo16,
+ PciResUsageTypical
+ );
+
+ Mem32Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem32,
+ PciResUsageTypical
+ );
+
+ PMem32Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem32,
+ PciResUsageTypical
+ );
+
+ Mem64Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem64,
+ PciResUsageTypical
+ );
+
+ PMem64Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem64,
+ PciResUsageTypical
+ );
+
+ //
+ // Create resourcemap by going through all the devices subject to this root bridge
+ //
+ Status = CreateResourceMap (
+ RootBridgeDev,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge
+ );
+
+ //
+ // Get the max ROM size that the root bridge can process
+ //
+ RootBridgeDev->RomSize = Mem32Bridge->Length;
+
+ //
+ // Get Max Option Rom size for current root bridge
+ //
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);
+
+ //
+ // Enlarger the mem32 resource to accomdate the option rom
+ // if the mem32 resource is not enough to hold the rom
+ //
+ if (MaxOptionRomSize > Mem32Bridge->Length) {
+
+ Mem32Bridge->Length = MaxOptionRomSize;
+ RootBridgeDev->RomSize = MaxOptionRomSize;
+
+ //
+ // Alignment should be adjusted as well
+ //
+ if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {
+ Mem32Bridge->Alignment = MaxOptionRomSize - 1;
+ }
+ }
+
+ //
+ // Based on the all the resource tree, contruct ACPI resource node to
+ // submit the resource aperture to pci host bridge protocol
+ //
+ Status = ConstructAcpiResourceRequestor (
+ RootBridgeDev,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge,
+ &AcpiConfig
+ );
+
+ //
+ // Insert these resource nodes into the database
+ //
+ InsertResourceNode (&IoPool, IoBridge);
+ InsertResourceNode (&Mem32Pool, Mem32Bridge);
+ InsertResourceNode (&PMem32Pool, PMem32Bridge);
+ InsertResourceNode (&Mem64Pool, Mem64Bridge);
+ InsertResourceNode (&PMem64Pool, PMem64Bridge);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Submit the resource requirement
+ //
+ Status = PciResAlloc->SubmitResources (
+ PciResAlloc,
+ RootBridgeDev->Handle,
+ AcpiConfig
+ );
+ }
+ //
+ // Free acpi resource node
+ //
+ if (AcpiConfig) {
+ gBS->FreePool (AcpiConfig);
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Destroy all the resource tree
+ //
+ DestroyResourceTree (&IoPool);
+ DestroyResourceTree (&Mem32Pool);
+ DestroyResourceTree (&PMem32Pool);
+ DestroyResourceTree (&Mem64Pool);
+ DestroyResourceTree (&PMem64Pool);
+ return Status;
+ }
+ }
+ //
+ // End while
+ //
+
+ //
+ // Notify pci bus driver starts to program the resource
+ //
+ Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Allocation failed, then return
+ //
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Raise the EFI_IOB_PCI_RES_ALLOC status code
+ //
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,
+ (VOID *) &ExtendedData,
+ sizeof (ExtendedData)
+ );
+
+ //
+ // Notify pci bus driver starts to program the resource
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);
+
+ RootBridgeDev = NULL;
+
+ RootBridgeHandle = 0;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get acpi resource node for all the resource types
+ //
+ AcpiConfig = NULL;
+ Status = PciResAlloc->GetProposedResources (
+ PciResAlloc,
+ RootBridgeDev->Handle,
+ &AcpiConfig
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the resource base by interpreting acpi resource node
+ //
+ //
+ GetResourceBase (
+ AcpiConfig,
+ &IoBase,
+ &Mem32Base,
+ &PMem32Base,
+ &Mem64Base,
+ &PMem64Base
+ );
+
+ //
+ // Process option rom for this root bridge
+ //
+ Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);
+
+ //
+ // Create the entire system resource map from the information collected by
+ // enumerator. Several resource tree was created
+ //
+ Status = GetResourceMap (
+ RootBridgeDev,
+ &IoBridge,
+ &Mem32Bridge,
+ &PMem32Bridge,
+ &Mem64Bridge,
+ &PMem64Bridge,
+ &IoPool,
+ &Mem32Pool,
+ &PMem32Pool,
+ &Mem64Pool,
+ &PMem64Pool
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Program IO resources
+ //
+ ProgramResource (
+ IoBase,
+ IoBridge
+ );
+
+ //
+ // Program Mem32 resources
+ //
+ ProgramResource (
+ Mem32Base,
+ Mem32Bridge
+ );
+
+ //
+ // Program PMem32 resources
+ //
+ ProgramResource (
+ PMem32Base,
+ PMem32Bridge
+ );
+
+ //
+ // Program Mem64 resources
+ //
+ ProgramResource (
+ Mem64Base,
+ Mem64Bridge
+ );
+
+ //
+ // Program PMem64 resources
+ //
+ ProgramResource (
+ PMem64Base,
+ PMem64Bridge
+ );
+
+ if (AcpiConfig != NULL) {
+ gBS->FreePool (AcpiConfig);
+ }
+ }
+
+ //
+ // Destroy all the resource tree
+ //
+ DestroyResourceTree (&IoPool);
+ DestroyResourceTree (&Mem32Pool);
+ DestroyResourceTree (&PMem32Pool);
+ DestroyResourceTree (&Mem64Pool);
+ DestroyResourceTree (&PMem64Pool);
+
+ //
+ // Notify the resource allocation phase is to end
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciScanBus (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to assign bus number to the given PCI bus system
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: StartBusNumber - add argument and description to function comment
+// TODO: SubBusNumber - add argument and description to function comment
+// TODO: PaddedBusRange - add argument and description to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_TYPE00 Pci;
+ UINT8 Device;
+ UINT8 Func;
+ UINT64 Address;
+ UINTN SecondBus;
+ UINT16 Register;
+ PCI_IO_DEVICE *PciDevice;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+ SecondBus = 0;
+ Register = 0;
+
+ ResetAllPpbBusReg (Bridge, StartBusNumber);
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+ //
+ // Check to see whether a pci device is present
+ //
+ Status = PciDevicePresent (
+ PciRootBridgeIo,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func
+ );
+
+ if (!EFI_ERROR (Status) &&
+ (IS_PCI_BRIDGE (&Pci) ||
+ IS_CARDBUS_BRIDGE (&Pci))) {
+
+ //
+ // Get the bridge information
+ //
+ Status = PciSearchDevice (
+ Bridge,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func,
+ &PciDevice
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ (*SubBusNumber)++;
+
+ SecondBus = (*SubBusNumber);
+
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
+
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint16,
+ Address,
+ 1,
+ &Register
+ );
+
+ //
+ // Initialize SubBusNumber to SecondBus
+ //
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ SubBusNumber
+ );
+ //
+ // If it is PPB, resursively search down this bridge
+ //
+ if (IS_PCI_BRIDGE (&Pci)) {
+ //
+ // Temporarily initialize SubBusNumber to maximum bus number to ensure the
+ // PCI configuration transaction to go through any PPB
+ //
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+ Register = 0xFF;
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ &Register
+ );
+
+ PreprocessController (
+ PciDevice,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ EfiPciBeforeChildBusEnumeration
+ );
+
+ Status = PciScanBus (
+ PciDevice,
+ (UINT8) (SecondBus),
+ SubBusNumber,
+ PaddedBusRange
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Set the current maximum bus number under the PPB
+ //
+
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ SubBusNumber
+ );
+
+ }
+
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+
+ Func = PCI_MAX_FUNC;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Light PCI bus driver woundn't support P2C
+// Return instead
+//
+EFI_STATUS
+PciHostBridgeP2CProcess (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ return EFI_SUCCESS;
+}
+
+//
+// Light PCI bus driver woundn't support hotplug device
+// Simplified the code
+//
+EFI_STATUS
+PciHostBridgeEnumerator (
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ This function is used to enumerate the entire host bridge
+ in a given platform
+
+Arguments:
+
+ PciResAlloc A pointer to the protocol to allocate resource.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE RootBridgeHandle;
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ UINT16 MinBus;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+
+ InitializeHotPlugSupport ();
+
+ //
+ // Notify the bus allocation phase is about to start
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
+
+ RootBridgeHandle = NULL;
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
+
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Enumerate all the buses under this root bridge
+ //
+
+ Status = PciRootBridgeEnumerator (
+ PciResAlloc,
+ RootBridgeDev
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DestroyRootBridge (RootBridgeDev);
+
+ //
+ // Error proccess here
+ //
+ }
+
+ //
+ // Notify the bus allocation phase is to end
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
+
+ //
+ // Notify the resource allocation phase is to start
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);
+
+ RootBridgeHandle = NULL;
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
+
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = StartManagingRootBridge (RootBridgeDev);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Determine root bridge attribute by calling interface of Pcihostbridge
+ // protocol
+ //
+ DetermineRootBridgeAttributes (
+ PciResAlloc,
+ RootBridgeDev
+ );
+
+ //
+ // Collect all the resource information under this root bridge
+ // A database that records all the information about pci device subject to this
+ // root bridge will then be created
+ //
+ Status = PciPciDeviceInfoCollector (
+ RootBridgeDev,
+ (UINT8) MinBus
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ InsertRootBridge (RootBridgeDev);
+
+ //
+ // Record the hostbridge handle
+ //
+ AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd new file mode 100644 index 0000000000..41543f7832 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>PciBus</BaseName>
+ <Guid>93B80004-9FB3-11d4-9A3A-0090273FC14D</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:18</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>UefiDriverModelLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>EdkDxePrintLib</Library>
+ <Library>BaseLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ <Library>UefiDevicePathLib</Library>
+ </Libraries>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa new file mode 100644 index 0000000000..bf5c3698ef --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>PciBus</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>93B80004-9FB3-11d4-9A3A-0090273FC14D</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for PciBus module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:18</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>PciBus.h</Filename>
+ <Filename>PciIo.h</Filename>
+ <Filename>PciCommand.h</Filename>
+ <Filename>PciDeviceSupport.h</Filename>
+ <Filename>PciResourceSupport.h</Filename>
+ <Filename>PciEnumerator.h</Filename>
+ <Filename>PciEnumeratorSupport.h</Filename>
+ <Filename>PciOptionRomSupport.h</Filename>
+ <Filename>PciRomTable.h</Filename>
+ <Filename>PciHotPlugSupport.h</Filename>
+ <Filename>PciLib.h</Filename>
+ <Filename>PciHotPlugSupport.c</Filename>
+ <Filename>PciRomTable.c</Filename>
+ <Filename>PciDriverOverride.h</Filename>
+ <Filename>PciPowerManagement.h</Filename>
+ <Filename>PciPowerManagement.c</Filename>
+ <Filename>PciDriverOverride.c</Filename>
+ <Filename>PciOptionRomSupport.c</Filename>
+ <Filename>PciEnumerator.c</Filename>
+ <Filename>PciEnumeratorSupport.c</Filename>
+ <Filename>PciResourceSupport.c</Filename>
+ <Filename>PciCOmmand.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ <Filename>PciDeviceSupport.c</Filename>
+ <Filename>PciBus.c</Filename>
+ <Filename>PciIo.c</Filename>
+ <Filename>PciLib.c</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="TO_START">DevicePath</Protocol>
+ <Protocol Usage="TO_START">PciRootBridgeIo</Protocol>
+ <Protocol Usage="TO_START">PciPlatform</Protocol>
+ <Protocol Usage="TO_START">IncompatiblePciDeviceSupport</Protocol>
+ <Protocol Usage="TO_START">PciHostBridgeResourceAllocation</Protocol>
+ <Protocol Usage="TO_START">PciHotPlugInit</Protocol>
+ <Protocol Usage="TO_START">Decompress</Protocol>
+ <Protocol Usage="TO_START">LoadedImage</Protocol>
+ <Protocol Usage="TO_START">UgaIo</Protocol>
+ <Protocol Usage="BY_START">PciIo</Protocol>
+ <Protocol Usage="BY_START">BusSpecificDriverOverride</Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">PciHotPlugRequest</Protocol>
+ </Protocols>
+ <SystemTables>
+ <SystemTable Usage="ALWAYS_CONSUMED">
+ <Entry>gEfiUgaIoProtocolGuid</Entry>
+ </SystemTable>
+ <SystemTable Usage="SOMETIMES_CONSUMED">
+ <Entry>gEfiPciOptionRomTableGuid</Entry>
+ </SystemTable>
+ </SystemTables>
+ <Guids>
+ <GuidEntry Usage="SOMETIMES_CONSUMED">
+ <C_Name>PciOptionRomTable</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="SOMETIMES_CONSUMED">
+ <C_Name>StatusCodeSpecificData</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="PRIVATE">
+ <C_Name>PciHotplugDevice</C_Name>
+ </GuidEntry>
+ </Guids>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <DriverBinding>gPciBusDriverBinding</DriverBinding>
+ <ComponentName>gPciBusComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd new file mode 100644 index 0000000000..c02965265c --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>PciBusPciBusLite</BaseName>
+ <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:18</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>UefiDriverModelLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>EdkDxePrintLib</Library>
+ <Library>BaseLib</Library>
+ <Library>UefiDevicePathLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ </Libraries>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa new file mode 100644 index 0000000000..1568b31e31 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>PciBusPciBusLite</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for LightPciBus module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:18</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>PciBus.h</Filename>
+ <Filename>PciIo.h</Filename>
+ <Filename>PciCommand.h</Filename>
+ <Filename>PciDeviceSupport.h</Filename>
+ <Filename>PciResourceSupport.h</Filename>
+ <Filename>PciEnumerator.h</Filename>
+ <Filename>PciEnumeratorSupport.h</Filename>
+ <Filename>PciOptionRomSupport.h</Filename>
+ <Filename>PciRomTable.h</Filename>
+ <Filename>PciLib.h</Filename>
+ <Filename>PciRomTable.c</Filename>
+ <Filename>PciDriverOverride.h</Filename>
+ <Filename>PciPowerManagement.h</Filename>
+ <Filename>PciPowerManagement.c</Filename>
+ <Filename>PciDriverOverride.c</Filename>
+ <Filename>PciOptionRomSupport.c</Filename>
+ <Filename>PciEnumerator.c</Filename>
+ <Filename>PciEnumeratorSupport.c</Filename>
+ <Filename>PciResourceSupport.c</Filename>
+ <Filename>PciCOmmand.c</Filename>
+ <Filename>PciDeviceSupport.c</Filename>
+ <Filename>PciHotPlugSupport.c</Filename>
+ <Filename>PciBus.c</Filename>
+ <Filename>PciIo.c</Filename>
+ <Filename>LightPciLib.c</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciRootBridgeIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">UgaIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciPlatform</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">BusSpecificDriverOverride</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugRequest</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">IncompatiblePciDeviceSupport</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugInit</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">PciHostBridgeResourceAllocation</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>
+ </Protocols>
+ <Guids>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>PciOptionRomTable</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>PciHotplugDevice</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>StatusCodeSpecificData</C_Name>
+ </GuidEntry>
+ </Guids>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <DriverBinding>gPciBusDriverBinding</DriverBinding>
+ <ComponentName>gPciBusComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c new file mode 100644 index 0000000000..90712338f0 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c @@ -0,0 +1,207 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciCommand.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+
+EFI_STATUS
+PciOperateRegister (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 Command,
+ IN UINT8 Offset,
+ IN UINT8 Operation,
+ OUT UINT16 *PtrCommand
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Command - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: PtrCommand - add argument and description to function comment
+{
+ UINT16 OldCommand;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ OldCommand = 0;
+ PciIo = &PciIoDevice->PciIo;
+
+ if (Operation != EFI_SET_REGISTER) {
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint16,
+ Offset,
+ 1,
+ &OldCommand
+ );
+
+ if (Operation == EFI_GET_REGISTER) {
+ *PtrCommand = OldCommand;
+ return Status;
+ }
+ }
+
+ if (Operation == EFI_ENABLE_REGISTER) {
+ OldCommand |= Command;
+ } else if (Operation == EFI_DISABLE_REGISTER) {
+ OldCommand &= ~(Command);
+ } else {
+ OldCommand = Command;
+ }
+
+ return PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ Offset,
+ 1,
+ &OldCommand
+ );
+}
+
+BOOLEAN
+PciCapabilitySupport (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+{
+
+ if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+LocateCapabilityRegBlock (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT8 CapId,
+ IN OUT UINT8 *Offset,
+ OUT UINT8 *NextRegBlock OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Locate cap reg.
+
+Arguments:
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+ CapId - The cap ID.
+ Offset - A pointer to the offset.
+ NextRegBlock - A pointer to the next block.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ UINT8 CapabilityPtr;
+ UINT16 CapabilityEntry;
+ UINT8 CapabilityID;
+
+ //
+ // To check the cpability of this device supports
+ //
+ if (!PciCapabilitySupport (PciIoDevice)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (*Offset != 0) {
+ CapabilityPtr = *Offset;
+ } else {
+
+ CapabilityPtr = 0;
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+
+ PciIoDevice->PciIo.Pci.Read (
+ &PciIoDevice->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
+ 1,
+ &CapabilityPtr
+ );
+ } else {
+
+ PciIoDevice->PciIo.Pci.Read (
+ &PciIoDevice->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_CAPABILITY_PTR,
+ 1,
+ &CapabilityPtr
+ );
+ }
+ }
+
+ while (CapabilityPtr > 0x3F) {
+ //
+ // Mask it to DWORD alignment per PCI spec
+ //
+ CapabilityPtr &= 0xFC;
+ PciIoDevice->PciIo.Pci.Read (
+ &PciIoDevice->PciIo,
+ EfiPciIoWidthUint16,
+ CapabilityPtr,
+ 1,
+ &CapabilityEntry
+ );
+
+ CapabilityID = (UINT8) CapabilityEntry;
+
+ if (CapabilityID == CapId) {
+ *Offset = CapabilityPtr;
+ if (NextRegBlock != NULL) {
+ *NextRegBlock = (UINT8) (CapabilityEntry >> 8);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h new file mode 100644 index 0000000000..56f632e8da --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h @@ -0,0 +1,134 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciCommand.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_COMMAND_H
+#define _EFI_PCI_COMMAND_H
+
+#define EFI_GET_REGISTER 1
+#define EFI_SET_REGISTER 2
+#define EFI_ENABLE_REGISTER 3
+#define EFI_DISABLE_REGISTER 4
+
+EFI_STATUS
+PciOperateRegister (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 Command,
+ IN UINT8 Offset,
+ IN UINT8 Operation,
+ OUT UINT16 *PtrCommand
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Command - TODO: add argument description
+ Offset - TODO: add argument description
+ Operation - TODO: add argument description
+ PtrCommand - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+PciCapabilitySupport (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+LocateCapabilityRegBlock (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT8 CapId,
+ IN OUT UINT8 *Offset,
+ OUT UINT8 *NextRegBlock OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ CapId - TODO: add argument description
+ Offset - TODO: add argument description
+ NextRegBlock - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+
+#define PciReadCommandRegister(a,b) \
+ PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b)
+
+#define PciSetCommandRegister(a,b) \
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL)
+
+#define PciEnableCommandRegister(a,b) \
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL)
+
+#define PciDisableCommandRegister(a,b) \
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL)
+
+#define PciReadBridgeControlRegister(a,b) \
+ PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b)
+
+#define PciSetBridgeControlRegister(a,b) \
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL)
+
+#define PciEnableBridgeControlRegister(a,b) \
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL)
+
+#define PciDisableBridgeControlRegister(a,b) \
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL)
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c new file mode 100644 index 0000000000..c24d1b5e59 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c @@ -0,0 +1,1345 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciDeviceSupport.c
+
+Abstract:
+
+ This file provides routine to support Pci device node manipulation
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+#include "PciDeviceSupport.h"
+
+//
+// This device structure is serviced as a header.
+// Its Next field points to the first root bridge device node
+//
+LIST_ENTRY gPciDevicePool;
+
+EFI_STATUS
+InitializePciDevicePool (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize the gPciDevicePool
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ InitializeListHead (&gPciDevicePool);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InsertRootBridge (
+ PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+ Insert a root bridge into PCI device pool
+
+Arguments:
+
+ RootBridge - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ InsertTailList (&gPciDevicePool, &(RootBridge->Link));
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InsertPciDevice (
+ PCI_IO_DEVICE *Bridge,
+ PCI_IO_DEVICE *PciDeviceNode
+ )
+/*++
+
+Routine Description:
+
+ This function is used to insert a PCI device node under
+ a bridge
+
+Arguments:
+ Bridge - A pointer to the PCI_IO_DEVICE.
+ PciDeviceNode - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));
+ PciDeviceNode->Parent = Bridge;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyRootBridge (
+ IN PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+ RootBridge - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ DestroyPciDeviceTree (RootBridge);
+
+ FreePciDevice (RootBridge);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FreePciDevice (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Destroy a pci device node.
+ Also all direct or indirect allocated resource for this node will be freed.
+
+Arguments:
+
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ //
+ // Assume all children have been removed underneath this device
+ //
+ if (PciIoDevice->ResourcePaddingDescriptors != NULL) {
+ gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors);
+ }
+
+ if (PciIoDevice->DevicePath != NULL) {
+ gBS->FreePool (PciIoDevice->DevicePath);
+ }
+
+ gBS->FreePool (PciIoDevice);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyPciDeviceTree (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ Destroy all the pci device node under the bridge.
+ Bridge itself is not included.
+
+Arguments:
+
+ Bridge - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+
+ while (!IsListEmpty (&Bridge->ChildList)) {
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ //
+ // Remove this node from the linked list
+ //
+ RemoveEntryList (CurrentLink);
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ DestroyPciDeviceTree (Temp);
+ }
+
+ FreePciDevice (Temp);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyRootBridgeByHandle (
+ EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ Destroy all device nodes under the root bridge
+ specified by Controller.
+ The root bridge itself is also included.
+
+Arguments:
+
+ Controller - An efi handle.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+
+ CurrentLink = gPciDevicePool.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (Temp->Handle == Controller) {
+
+ RemoveEntryList (CurrentLink);
+
+ DestroyPciDeviceTree (Temp);
+
+ FreePciDevice (Temp);
+
+ return EFI_SUCCESS;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+RegisterPciDevice (
+ IN EFI_HANDLE Controller,
+ IN PCI_IO_DEVICE *PciIoDevice,
+ OUT EFI_HANDLE *Handle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ This function is used to register the PCI device to the EFI,
+ create a handle for this PCI device,then attach apporpriate protocols
+ onto the handle.
+
+Arguments:
+
+ Controller - An efi handle.
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+ Handle - A pointer to a efi handle.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ VOID *PlatformOpRomBuffer;
+ UINTN PlatformOpRomSize;
+ UINT8 PciExpressCapRegOffset;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ //
+ // Install the pciio protocol, device path protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &PciIoDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ PciIoDevice->DevicePath,
+ &gEfiPciIoProtocolGuid,
+ &PciIoDevice->PciIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Detect if PCI Express Device
+ //
+ PciExpressCapRegOffset = 0;
+ Status = LocateCapabilityRegBlock (
+ PciIoDevice,
+ EFI_PCI_CAPABILITY_ID_PCIEXP,
+ &PciExpressCapRegOffset,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ PciIoDevice->IsPciExp = TRUE;
+ }
+
+ //
+ // Force Interrupt line to zero for cards that come up randomly
+ //
+ PciIo = &(PciIoDevice->PciIo);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);
+ //
+ // Process Platform OpRom
+ //
+ if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {
+ PciIoDevice->AllOpRomProcessed = TRUE;
+
+ Status = gPciPlatformProtocol->GetPciRom (
+ gPciPlatformProtocol,
+ PciIoDevice->Handle,
+ &PlatformOpRomBuffer,
+ &PlatformOpRomSize
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Have Platform OpRom
+ //
+ PciIoDevice->RomSize = PlatformOpRomSize;
+ PciIoDevice->PciIo.RomSize = PlatformOpRomSize;
+ PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;
+
+ //
+ // Process Image
+ //
+ ProcessOpRomImage (PciIoDevice);
+ }
+ }
+
+ if (PciIoDevice->BusOverride) {
+ //
+ // Install BusSpecificDriverOverride Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &PciIoDevice->Handle,
+ &gEfiBusSpecificDriverOverrideProtocolGuid,
+ &PciIoDevice->PciDriverOverride,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ &PciIoDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ PciIoDevice->DevicePath,
+ &gEfiPciIoProtocolGuid,
+ &PciIoDevice->PciIo,
+ NULL
+ );
+
+ return Status;
+ }
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &(PciIoDevice->PciRootBridgeIo),
+ gPciBusDriverBinding.DriverBindingHandle,
+ PciIoDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Install Pccard Hotplug GUID for Pccard device so that
+ // to notify CardBus driver to stop the device when de-register happens
+ //
+ InstallPciHotplugGuid (PciIoDevice);
+
+ if (Handle != NULL) {
+ *Handle = PciIoDevice->Handle;
+ }
+
+ //
+ // Indicate the pci device is registered
+ //
+ PciIoDevice->Registered = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RemoveAllPciDeviceOnBridge (
+ EFI_HANDLE RootBridgeHandle,
+ PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ This function is used to remove the whole PCI devices from the bridge.
+
+Arguments:
+
+ RootBridgeHandle - An efi handle.
+ Bridge - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+
+ while (!IsListEmpty (&Bridge->ChildList)) {
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ //
+ // Check if the current node has been deregistered before
+ // If it is not, then deregister it
+ //
+ if (Temp->Registered) {
+ DeRegisterPciDevice (RootBridgeHandle, Temp->Handle);
+ }
+
+ //
+ // Remove this node from the linked list
+ //
+ RemoveEntryList (CurrentLink);
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);
+ }
+
+ FreePciDevice (Temp);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeRegisterPciDevice (
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ This function is used to de-register the PCI device from the EFI,
+ That includes un-installing PciIo protocol from the specified PCI
+ device handle.
+
+Arguments:
+
+ Controller - An efi handle.
+ Handle - An efi handle.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+ PCI_IO_DEVICE *Node;
+ LIST_ENTRY *CurrentLink;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
+
+ //
+ // If it is already de-registered
+ //
+ if (!PciIoDevice->Registered) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If it is PPB, first de-register its children
+ //
+
+ if (!IsListEmpty (&PciIoDevice->ChildList)) {
+
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
+ Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ Status = DeRegisterPciDevice (Controller, Node->Handle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+ }
+ //
+ // Uninstall Pccard Hotplug GUID for Pccard device
+ //
+ UninstallPciHotplugGuid (PciIoDevice);
+
+ //
+ // Close the child handle
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // Un-install the device path protocol and pci io protocol
+ //
+ if (PciIoDevice->BusOverride) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ PciIoDevice->DevicePath,
+ &gEfiPciIoProtocolGuid,
+ &PciIoDevice->PciIo,
+ &gEfiBusSpecificDriverOverrideProtocolGuid,
+ &PciIoDevice->PciDriverOverride,
+ NULL
+ );
+ } else {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ PciIoDevice->DevicePath,
+ &gEfiPciIoProtocolGuid,
+ &PciIoDevice->PciIo,
+ NULL
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ return Status;
+ }
+
+ //
+ // The Device Driver should disable this device after disconnect
+ // so the Pci Bus driver will not touch this device any more.
+ // Restore the register field to the original value
+ //
+ PciIoDevice->Registered = FALSE;
+ PciIoDevice->Handle = NULL;
+ } else {
+
+ //
+ // Handle may be closed before
+ //
+ return EFI_SUCCESS;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StartPciDevicesOnBridge (
+ IN EFI_HANDLE Controller,
+ IN PCI_IO_DEVICE *RootBridge,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN OUT UINT8 *NumberOfChildren,
+ IN OUT EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
+
+Arguments:
+
+ Controller - An efi handle.
+ RootBridge - A pointer to the PCI_IO_DEVICE.
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+ NumberOfChildren - Children number.
+ ChildHandleBuffer - A pointer to the child handle buffer.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_NOT_READY - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ PCI_IO_DEVICE *Temp;
+ PCI_IO_DEVICE *PciIoDevice;
+ EFI_DEV_PATH_PTR Node;
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
+ EFI_STATUS Status;
+ LIST_ENTRY *CurrentLink;
+ UINT64 Supports;
+
+ CurrentLink = RootBridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (RemainingDevicePath != NULL) {
+
+ Node.DevPath = RemainingDevicePath;
+
+ if (Node.Pci->Device != Temp->DeviceNumber ||
+ Node.Pci->Function != Temp->FunctionNumber) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ //
+ // Check if the device has been assigned with required resource
+ //
+ if (!Temp->Allocated) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Check if the current node has been registered before
+ // If it is not, register it
+ //
+ if (!Temp->Registered) {
+ PciIoDevice = Temp;
+
+ Status = RegisterPciDevice (
+ Controller,
+ PciIoDevice,
+ NULL
+ );
+
+ }
+
+ if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {
+ ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;
+ (*NumberOfChildren)++;
+ }
+
+ //
+ // Get the next device path
+ //
+ CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If it is a PPB
+ //
+ if (!IsListEmpty (&Temp->ChildList)) {
+ Status = StartPciDevicesOnBridge (
+ Controller,
+ Temp,
+ CurrentDevicePath,
+ NumberOfChildren,
+ ChildHandleBuffer
+ );
+
+ Temp->PciIo.Attributes (
+ &(Temp->PciIo),
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &Supports
+ );
+ Supports &= EFI_PCI_DEVICE_ENABLE;
+ Temp->PciIo.Attributes (
+ &(Temp->PciIo),
+ EfiPciIoAttributeOperationEnable,
+ Supports,
+ NULL
+ );
+
+ return Status;
+ } else {
+
+ //
+ // Currently, the PCI bus driver only support PCI-PCI bridge
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ } else {
+
+ //
+ // If remaining device path is NULL,
+ // try to enable all the pci devices under this bridge
+ //
+
+ if (!Temp->Registered && Temp->Allocated) {
+
+ PciIoDevice = Temp;
+
+ Status = RegisterPciDevice (
+ Controller,
+ PciIoDevice,
+ NULL
+ );
+
+ }
+
+ if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {
+ ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;
+ (*NumberOfChildren)++;
+ }
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ Status = StartPciDevicesOnBridge (
+ Controller,
+ Temp,
+ RemainingDevicePath,
+ NumberOfChildren,
+ ChildHandleBuffer
+ );
+
+ Temp->PciIo.Attributes (
+ &(Temp->PciIo),
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &Supports
+ );
+ Supports &= EFI_PCI_DEVICE_ENABLE;
+ Temp->PciIo.Attributes (
+ &(Temp->PciIo),
+ EfiPciIoAttributeOperationEnable,
+ Supports,
+ NULL
+ );
+
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+StartPciDevices (
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ Start to manage the PCI device according to RemainingDevicePath
+ If RemainingDevicePath == NULL, the PCI bus driver will start
+ to manage all the PCI devices it found previously
+
+Arguments:
+ Controller - An efi handle.
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_DEV_PATH_PTR Node;
+ PCI_IO_DEVICE *RootBridge;
+ LIST_ENTRY *CurrentLink;
+
+ if (RemainingDevicePath != NULL) {
+
+ //
+ // Check if the RemainingDevicePath is valid
+ //
+ Node.DevPath = RemainingDevicePath;
+ if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||
+ ((Node.DevPath->SubType != HW_PCI_DP) &&
+ (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))
+ ) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ CurrentLink = gPciDevicePool.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+ RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ //
+ // Locate the right root bridge to start
+ //
+ if (RootBridge->Handle == Controller) {
+ StartPciDevicesOnBridge (
+ Controller,
+ RootBridge,
+ RemainingDevicePath,
+ NULL,
+ NULL
+ );
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+CreateRootBridge (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+ RootBridgeHandle - An efi handle.
+
+Returns:
+
+ None
+
+--*/
+{
+
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *Dev;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ Dev = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (PCI_IO_DEVICE),
+ (VOID **) &Dev
+ );
+
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ ZeroMem (Dev, sizeof (PCI_IO_DEVICE));
+ Dev->Signature = PCI_IO_DEVICE_SIGNATURE;
+ Dev->Handle = RootBridgeHandle;
+ InitializeListHead (&Dev->ChildList);
+
+ Status = gBS->OpenProtocol (
+ RootBridgeHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ gPciBusDriverBinding.DriverBindingHandle,
+ RootBridgeHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (Dev);
+ return NULL;
+ }
+
+ //
+ // Record the root bridge parent device path
+ //
+ Dev->DevicePath = DuplicateDevicePath (ParentDevicePath);
+
+ //
+ // Get the pci root bridge io protocol
+ //
+ Status = gBS->OpenProtocol (
+ RootBridgeHandle,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ RootBridgeHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePciDevice (Dev);
+ return NULL;
+ }
+
+ Dev->PciRootBridgeIo = PciRootBridgeIo;
+
+ //
+ // Initialize the PCI I/O instance structure
+ //
+ Status = InitializePciIoInstance (Dev);
+ Status = InitializePciDriverOverrideInstance (Dev);
+
+ //
+ // Initialize reserved resource list and
+ // option rom driver list
+ //
+ InitializeListHead (&Dev->ReservedResourceList);
+ InitializeListHead (&Dev->OptionRomDriverList);
+
+ return Dev;
+}
+
+PCI_IO_DEVICE *
+GetRootBridgeByHandle (
+ EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+ RootBridgeHandle - An efi handle.
+
+Returns:
+
+ None
+
+--*/
+{
+ PCI_IO_DEVICE *RootBridgeDev;
+ LIST_ENTRY *CurrentLink;
+
+ CurrentLink = gPciDevicePool.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+ RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (RootBridgeDev->Handle == RootBridgeHandle) {
+ return RootBridgeDev;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return NULL;
+}
+
+BOOLEAN
+RootBridgeExisted (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ This function searches if RootBridgeHandle has already existed
+ in current device pool.
+
+ If so, it means the given root bridge has been already enumerated.
+
+Arguments:
+
+ RootBridgeHandle - An efi handle.
+
+Returns:
+
+ None
+
+--*/
+{
+ PCI_IO_DEVICE *Bridge;
+
+ Bridge = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (Bridge != NULL) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+PciDeviceExisted (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ Bridge - A pointer to the PCI_IO_DEVICE.
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+
+ PCI_IO_DEVICE *Temp;
+ LIST_ENTRY *CurrentLink;
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (Temp == PciIoDevice) {
+ return TRUE;
+ }
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ if (PciDeviceExisted (Temp, PciIoDevice)) {
+ return TRUE;
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return FALSE;
+}
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheSameSegment (
+ IN PCI_IO_DEVICE *VgaDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ VgaDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+
+ CurrentLink = gPciDevicePool.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {
+
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);
+
+ if (Temp != NULL) {
+ return Temp;
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return NULL;
+}
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheRootBridge (
+ IN PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ RootBridge - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+
+ CurrentLink = RootBridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (IS_PCI_VGA(&Temp->Pci) &&
+ (Temp->Attributes & (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO))) {
+ return Temp;
+ }
+
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {
+
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);
+
+ if (Temp != NULL) {
+ return Temp;
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return NULL;
+}
+
+EFI_STATUS
+GetHpcPciAddress (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ OUT UINT64 *PciAddress
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
+ PciAddress - A pointer to the pci address.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
+ EFI_DEV_PATH_PTR Node;
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *RootBridge;
+ EFI_STATUS Status;
+
+ CurrentDevicePath = HpcDevicePath;
+
+ //
+ // Get the remaining device path for this PCI device, if it is a PCI device
+ //
+ while (!EfiIsDevicePathEnd (CurrentDevicePath)) {
+
+ Node.DevPath = CurrentDevicePath;
+
+ //
+ // Check if it is PCI device Path?
+ //
+ if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||
+ ((Node.DevPath->SubType != HW_PCI_DP) &&
+ (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) {
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
+ continue;
+ }
+
+ break;
+ }
+
+ //
+ // Check if it is not PCI device path
+ //
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CurrentLink = gPciDevicePool.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {
+
+ RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ //
+ // Locate the right root bridge to start
+ //
+ if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) {
+ Status = GetHpcPciAddressFromRootBridge (
+ RootBridge,
+ CurrentDevicePath,
+ PciAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetHpcPciAddressFromRootBridge (
+ IN PCI_IO_DEVICE *RootBridge,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ OUT UINT64 *PciAddress
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
+ PciAddress - A pointer to the pci address.
+
+Returns:
+
+ None
+
+--*/
+// TODO: RootBridge - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_DEV_PATH_PTR Node;
+ PCI_IO_DEVICE *Temp;
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
+ LIST_ENTRY *CurrentLink;
+ BOOLEAN MisMatch;
+
+ MisMatch = FALSE;
+
+ CurrentDevicePath = RemainingDevicePath;
+ Node.DevPath = CurrentDevicePath;
+ Temp = NULL;
+
+ while (!EfiIsDevicePathEnd (CurrentDevicePath)) {
+
+ CurrentLink = RootBridge->ChildList.ForwardLink;
+ Node.DevPath = CurrentDevicePath;
+
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (Node.Pci->Device == Temp->DeviceNumber &&
+ Node.Pci->Function == Temp->FunctionNumber) {
+ RootBridge = Temp;
+ break;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Check if we find the bridge
+ //
+ if (CurrentLink == &RootBridge->ChildList) {
+
+ MisMatch = TRUE;
+ break;
+
+ }
+
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
+ }
+
+ if (MisMatch) {
+
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
+
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {
+ *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+ }
+
+ *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);
+
+ return EFI_SUCCESS;
+
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h new file mode 100644 index 0000000000..374f4dfad3 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h @@ -0,0 +1,477 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciDeviceSupport.h
+
+Abstract:
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_DEVICE_SUPPORT_H
+#define _EFI_PCI_DEVICE_SUPPORT_H
+
+EFI_STATUS
+InitializePciDevicePool (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InsertRootBridge (
+ PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InsertPciDevice (
+ PCI_IO_DEVICE *Bridge,
+ PCI_IO_DEVICE *PciDeviceNode
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ PciDeviceNode - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyRootBridge (
+ IN PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyPciDeviceTree (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyRootBridgeByHandle (
+ EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RegisterPciDevice (
+ IN EFI_HANDLE Controller,
+ IN PCI_IO_DEVICE *PciIoDevice,
+ OUT EFI_HANDLE *Handle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+ PciIoDevice - TODO: add argument description
+ Handle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RemoveAllPciDeviceOnBridge (
+ EFI_HANDLE RootBridgeHandle,
+ PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DeRegisterPciDevice (
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+ Handle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+StartPciDevicesOnBridge (
+ IN EFI_HANDLE Controller,
+ IN PCI_IO_DEVICE *RootBridge,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN OUT UINT8 *NumberOfChildren,
+ IN OUT EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+ RootBridge - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+StartPciDevices (
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+CreateRootBridge (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+GetRootBridgeByHandle (
+ EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+RootBridgeExisted (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+PciDeviceExisted (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheSameSegment (
+ IN PCI_IO_DEVICE *VgaDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ VgaDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+ActiveVGADeviceOnTheRootBridge (
+ IN PCI_IO_DEVICE *RootBridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetHpcPciAddress (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ OUT UINT64 *PciAddress
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciRootBridgeIo - TODO: add argument description
+ HpcDevicePath - TODO: add argument description
+ PciAddress - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetHpcPciAddressFromRootBridge (
+ IN PCI_IO_DEVICE *RootBridge,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ OUT UINT64 *PciAddress
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridge - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+ PciAddress - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+FreePciDevice (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c new file mode 100644 index 0000000000..76c5a20784 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c @@ -0,0 +1,290 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciDriverOverride.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "pcibus.h"
+
+EFI_STATUS
+InitializePciDriverOverrideInstance (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Initializes a PCI Driver Override Instance
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetDriver (
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN OUT EFI_HANDLE *DriverImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Get a overriding driver image
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: DriverImageHandle - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ PCI_IO_DEVICE *PciIoDevice;
+ LIST_ENTRY *CurrentLink;
+ PCI_DRIVER_OVERRIDE_LIST *Node;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
+
+ CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {
+
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
+
+ if (*DriverImageHandle == NULL) {
+
+ *DriverImageHandle = Node->DriverImageHandle;
+ return EFI_SUCCESS;
+ }
+
+ if (*DriverImageHandle == Node->DriverImageHandle) {
+
+ if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
+ CurrentLink->ForwardLink == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get next node
+ //
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
+ *DriverImageHandle = Node->DriverImageHandle;
+ return EFI_SUCCESS;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+AddDriver (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_HANDLE DriverImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Add a overriding driver image
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: DriverImageHandle - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ PCI_DRIVER_OVERRIDE_LIST *Node;
+ EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;
+ EFI_DRIVER_OS_HANDOFF_HEADER *NewDriverOsHandoffHeader;
+ EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_HANDLE DeviceHandle;
+ UINTN NumberOfEntries;
+ UINTN Size;
+ UINTN Index;
+
+ Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
+ if (Node == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
+ Node->DriverImageHandle = DriverImageHandle;
+
+ InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
+
+ PciIoDevice->BusOverride = TRUE;
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ return EFI_SUCCESS;
+ }
+
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);
+
+ if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {
+ return EFI_SUCCESS;
+ }
+
+ DriverOsHandoffHeader = NULL;
+ Status = EfiGetSystemConfigurationTable (&gEfiUgaIoProtocolGuid, (VOID **) &DriverOsHandoffHeader);
+ if (!EFI_ERROR (Status) && DriverOsHandoffHeader != NULL) {
+ for (Index = 0; Index < DriverOsHandoffHeader->NumberOfEntries; Index++) {
+ DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)(DriverOsHandoffHeader) +
+ DriverOsHandoffHeader->HeaderSize +
+ Index * DriverOsHandoffHeader->SizeOfEntries);
+ DevicePath = DriverOsHandoff->DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);
+ if (!EFI_ERROR (Status) && DeviceHandle != NULL && IsDevicePathEnd (DevicePath)) {
+ if (DeviceHandle == PciIoDevice->Handle) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ NumberOfEntries = DriverOsHandoffHeader->NumberOfEntries + 1;
+ } else {
+ NumberOfEntries = 1;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (EFI_DRIVER_OS_HANDOFF_HEADER) + NumberOfEntries * sizeof (EFI_DRIVER_OS_HANDOFF),
+ (VOID **) &NewDriverOsHandoffHeader
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (DriverOsHandoffHeader == NULL) {
+ NewDriverOsHandoffHeader->Version = 0;
+ NewDriverOsHandoffHeader->HeaderSize = sizeof (EFI_DRIVER_OS_HANDOFF_HEADER);
+ NewDriverOsHandoffHeader->SizeOfEntries = sizeof (EFI_DRIVER_OS_HANDOFF);
+ NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;
+ } else {
+ gBS->CopyMem (
+ NewDriverOsHandoffHeader,
+ DriverOsHandoffHeader,
+ DriverOsHandoffHeader->HeaderSize + (NumberOfEntries - 1) * DriverOsHandoffHeader->SizeOfEntries
+ );
+ NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;
+ }
+
+ DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)NewDriverOsHandoffHeader +
+ NewDriverOsHandoffHeader->HeaderSize +
+ (NumberOfEntries - 1) * NewDriverOsHandoffHeader->SizeOfEntries);
+
+ //
+ // Fill in the EFI_DRIVER_OS_HANDOFF structure
+ //
+ DriverOsHandoff->Type = EfiUgaDriverFromPciRom;
+
+ //
+ // Compute the size of the device path
+ //
+ Size = GetDevicePathSize (PciIoDevice->DevicePath);
+ if (Size == 0) {
+ DriverOsHandoff->DevicePath = NULL;
+ } else {
+
+ //
+ // Allocate space for duplicate device path
+ //
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ Size,
+ (VOID **) &DriverOsHandoff->DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (NewDriverOsHandoffHeader);
+ return Status;
+ }
+
+ //
+ // Make copy of device path
+ //
+ CopyMem (DriverOsHandoff->DevicePath, PciIoDevice->DevicePath, Size);
+ }
+
+ DriverOsHandoff->PciRomSize = (UINT64) PciIoDevice->PciIo.RomSize;
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ (UINTN) DriverOsHandoff->PciRomSize,
+ (VOID **) &DriverOsHandoff->PciRomImage
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (NewDriverOsHandoffHeader);
+ return Status;
+ }
+
+ gBS->CopyMem (
+ DriverOsHandoff->PciRomImage,
+ PciIoDevice->PciIo.RomImage,
+ (UINTN) DriverOsHandoff->PciRomSize
+ );
+
+ Status = gBS->InstallConfigurationTable (&gEfiUgaIoProtocolGuid, NewDriverOsHandoffHeader);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (DriverOsHandoffHeader != NULL) {
+ gBS->FreePool (DriverOsHandoffHeader);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h new file mode 100644 index 0000000000..5992df9eb7 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h @@ -0,0 +1,108 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciDriverOverride.h
+
+Abstract:
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H
+#define _EFI_PCI_DRIVER_OVERRRIDE_H
+
+#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v')
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_HANDLE DriverImageHandle;
+} PCI_DRIVER_OVERRIDE_LIST;
+
+
+#define DRIVER_OVERRIDE_FROM_LINK(a) \
+ CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)
+
+
+EFI_STATUS
+InitializePciDriverOverrideInstance (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+AddDriver (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_HANDLE DriverImageHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ DriverImageHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetDriver (
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN OUT EFI_HANDLE *DriverImageHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ DriverImageHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c new file mode 100644 index 0000000000..d3566a1600 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c @@ -0,0 +1,2164 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciEnumerator.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+#include "PciEnumerator.h"
+#include "PciResourceSupport.h"
+#include "PciOptionRomSupport.h"
+
+EFI_STATUS
+PciEnumerator (
+ IN EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to enumerate entire pci bus system
+ in a given platform
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Controller - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ EFI_HANDLE HostBridgeHandle;
+ EFI_STATUS Status;
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ //
+ // If PCI bus has already done the full enumeration, never do it again
+ //
+ if (!gFullEnumeration) {
+ return PciEnumeratorLight (Controller);
+ }
+
+ //
+ // If this host bridge has been already enumerated, then return successfully
+ //
+ if (RootBridgeExisted (Controller)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Get the rootbridge Io protocol to find the host bridge handle
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the host bridge handle
+ //
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;
+
+ //
+ // Get the pci host bridge resource allocation protocol
+ //
+ Status = gBS->OpenProtocol (
+ HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+ (VOID **) &PciResAlloc,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Notify the pci bus enumeration is about to begin
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);
+
+ //
+ // Start the bus allocation phase
+ //
+ Status = PciHostBridgeEnumerator (PciResAlloc);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Submit the resource request
+ //
+ Status = PciHostBridgeResourceAllocator (PciResAlloc);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Process P2C
+ //
+ Status = PciHostBridgeP2CProcess (PciResAlloc);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Process attributes for devices on this host bridge
+ //
+ Status = PciHostBridgeDeviceAttribute (PciResAlloc);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gFullEnumeration = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRootBridgeEnumerator (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: RootBridgeDev - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;
+ UINT8 SubBusNumber;
+ UINT8 StartBusNumber;
+ UINT8 PaddedBusRange;
+ EFI_HANDLE RootBridgeHandle;
+
+ SubBusNumber = 0;
+ StartBusNumber = 0;
+ PaddedBusRange = 0;
+
+ //
+ // Get the root bridge handle
+ //
+ RootBridgeHandle = RootBridgeDev->Handle;
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,
+ RootBridgeDev->DevicePath
+ );
+
+ //
+ // Get the Bus information
+ //
+ Status = PciResAlloc->StartBusEnumeration (
+ PciResAlloc,
+ RootBridgeHandle,
+ (VOID **) &pConfiguration
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the bus number to start with
+ //
+ StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);
+
+ //
+ // Initialize the subordinate bus number
+ //
+ SubBusNumber = StartBusNumber;
+
+ //
+ // Assign bus number
+ //
+ Status = PciScanBus (
+ RootBridgeDev,
+ (UINT8) (pConfiguration->AddrRangeMin),
+ &SubBusNumber,
+ &PaddedBusRange
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
+ // Assign max bus number scanned
+ //
+ pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;
+
+ //
+ // Set bus number
+ //
+ Status = PciResAlloc->SetBusNumbers (
+ PciResAlloc,
+ RootBridgeHandle,
+ pConfiguration
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ProcessOptionRom (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT64 RomBase,
+ IN UINT64 MaxLength
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to process option rom on a certain root bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: RomBase - add argument and description to function comment
+// TODO: MaxLength - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+ EFI_STATUS Status;
+
+ //
+ // Go through bridges to reach all devices
+ //
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (!IsListEmpty (&Temp->ChildList)) {
+
+ //
+ // Go further to process the option rom under this bridge
+ //
+ Status = ProcessOptionRom (Temp, RomBase, MaxLength);
+ }
+
+ if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {
+
+ //
+ // Load and process the option rom
+ //
+ Status = LoadOpRomImage (Temp, RomBase);
+ if (Status == EFI_SUCCESS) {
+ Status = ProcessOpRomImage (Temp);
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciAssignBusNumber (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to assign bus number to the given PCI bus system
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: StartBusNumber - add argument and description to function comment
+// TODO: SubBusNumber - add argument and description to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_TYPE00 Pci;
+ UINT8 Device;
+ UINT8 Func;
+ UINT64 Address;
+ UINTN SecondBus;
+ UINT16 Register;
+ UINT8 Register8;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+
+ SecondBus = 0;
+ Register = 0;
+
+ *SubBusNumber = StartBusNumber;
+
+ //
+ // First check to see whether the parent is ppb
+ //
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+ //
+ // Check to see whether a pci device is present
+ //
+
+ Status = PciDevicePresent (
+ PciRootBridgeIo,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func
+ );
+
+ if (!EFI_ERROR (Status) &&
+ (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {
+
+ //
+ // Reserved one bus for cardbus bridge
+ //
+ SecondBus = ++(*SubBusNumber);
+
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
+
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint16,
+ Address,
+ 1,
+ &Register
+ );
+
+ //
+ // Initialize SubBusNumber to SecondBus
+ //
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ SubBusNumber
+ );
+ //
+ // If it is PPB, resursively search down this bridge
+ //
+ if (IS_PCI_BRIDGE (&Pci)) {
+
+ Register8 = 0xFF;
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ &Register8
+ );
+
+ Status = PciAssignBusNumber (
+ Bridge,
+ (UINT8) (SecondBus),
+ SubBusNumber
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Set the current maximum bus number under the PPB
+ //
+
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ SubBusNumber
+ );
+
+ }
+
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+
+ Func = PCI_MAX_FUNC;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DetermineRootBridgeAttributes (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to determine the root bridge attribute by interfacing
+ the host bridge resource allocation protocol.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: RootBridgeDev - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT64 Attributes;
+ EFI_STATUS Status;
+ EFI_HANDLE RootBridgeHandle;
+
+ Attributes = 0;
+ RootBridgeHandle = RootBridgeDev->Handle;
+
+ //
+ // Get root bridge attribute by calling into pci host bridge resource allocation protocol
+ //
+ Status = PciResAlloc->GetAllocAttributes (
+ PciResAlloc,
+ RootBridgeHandle,
+ &Attributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Here is the point where PCI bus driver calls HOST bridge allocation protocol
+ // Currently we hardcoded for ea815
+ //
+
+ if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;
+ }
+
+ if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
+ }
+
+ RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
+ RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;
+
+ return EFI_SUCCESS;
+}
+
+UINT64
+GetMaxOptionRomSize (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ Get Max Option Rom size on this bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+ UINT64 MaxOptionRomSize;
+ UINT64 TempOptionRomSize;
+
+ MaxOptionRomSize = 0;
+
+ //
+ // Go through bridges to reach all devices
+ //
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (!IsListEmpty (&Temp->ChildList)) {
+
+ //
+ // Get max option rom size under this bridge
+ //
+ TempOptionRomSize = GetMaxOptionRomSize (Temp);
+
+ //
+ // Compare with the option rom size of the bridge
+ // Get the larger one
+ //
+ if (Temp->RomSize > TempOptionRomSize) {
+ TempOptionRomSize = Temp->RomSize;
+ }
+
+ } else {
+
+ //
+ // For devices get the rom size directly
+ //
+ TempOptionRomSize = Temp->RomSize;
+ }
+
+ //
+ // Get the largest rom size on this bridge
+ //
+ if (TempOptionRomSize > MaxOptionRomSize) {
+ MaxOptionRomSize = TempOptionRomSize;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return MaxOptionRomSize;
+}
+
+EFI_STATUS
+PciHostBridgeDeviceAttribute (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ Process attributes of devices on this host bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE RootBridgeHandle;
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_STATUS Status;
+
+ RootBridgeHandle = NULL;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Set the attributes for devcies behind the Root Bridge
+ //
+ Status = DetermineDeviceAttribute (RootBridgeDev);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetResourceAllocationStatus (
+ VOID *AcpiConfig,
+ OUT UINT64 *IoResStatus,
+ OUT UINT64 *Mem32ResStatus,
+ OUT UINT64 *PMem32ResStatus,
+ OUT UINT64 *Mem64ResStatus,
+ OUT UINT64 *PMem64ResStatus
+ )
+/*++
+
+Routine Description:
+
+ Get resource allocation status from the ACPI pointer
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: AcpiConfig - add argument and description to function comment
+// TODO: IoResStatus - add argument and description to function comment
+// TODO: Mem32ResStatus - add argument and description to function comment
+// TODO: PMem32ResStatus - add argument and description to function comment
+// TODO: Mem64ResStatus - add argument and description to function comment
+// TODO: PMem64ResStatus - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ UINT8 *Temp;
+ UINT64 ResStatus;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
+
+ Temp = (UINT8 *) AcpiConfig;
+
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+ ResStatus = ptr->AddrTranslationOffset;
+
+ switch (ptr->ResType) {
+ case 0:
+ if (ptr->AddrSpaceGranularity == 32) {
+ if (ptr->SpecificFlag == 0x06) {
+ //
+ // Pmem32
+ //
+ *PMem32ResStatus = ResStatus;
+ } else {
+ //
+ // Mem32
+ //
+ *Mem32ResStatus = ResStatus;
+ }
+ }
+
+ if (ptr->AddrSpaceGranularity == 64) {
+ if (ptr->SpecificFlag == 0x06) {
+ //
+ // PMem64
+ //
+ *PMem64ResStatus = ResStatus;
+ } else {
+ //
+ // Mem64
+ //
+ *Mem64ResStatus = ResStatus;
+ }
+ }
+
+ break;
+
+ case 1:
+ //
+ // Io
+ //
+ *IoResStatus = ResStatus;
+ break;
+
+ default:
+ break;
+ }
+
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RejectPciDevice (
+ IN PCI_IO_DEVICE *PciDevice
+ )
+/*++
+
+Routine Description:
+
+ Remove a PCI device from device pool and mark its bar
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+{
+ PCI_IO_DEVICE *Bridge;
+ PCI_IO_DEVICE *Temp;
+ LIST_ENTRY *CurrentLink;
+
+ //
+ // Remove the padding resource from a bridge
+ //
+ if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \
+ PciDevice->ResourcePaddingDescriptors ) {
+ gBS->FreePool (PciDevice->ResourcePaddingDescriptors);
+ PciDevice->ResourcePaddingDescriptors = NULL;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Skip RB and PPB
+ //
+ if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {
+ return EFI_ABORTED;
+ }
+
+ if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {
+ //
+ // Get the root bridge device
+ //
+ Bridge = PciDevice;
+ while (Bridge->Parent) {
+ Bridge = Bridge->Parent;
+ }
+
+ RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);
+
+ //
+ // Mark its bar
+ //
+ InitializeP2C (PciDevice);
+ }
+
+ //
+ // Remove the device
+ //
+ Bridge = PciDevice->Parent;
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (Temp == PciDevice) {
+ InitializePciDevice (Temp);
+ RemoveEntryList (CurrentLink);
+ FreePciDevice (Temp);
+ return EFI_SUCCESS;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_ABORTED;
+}
+
+BOOLEAN
+IsRejectiveDevice (
+ IN PCI_RESOURCE_NODE *PciResNode
+ )
+/*++
+
+Routine Description:
+
+ Determine whethter a PCI device can be rejected
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResNode - add argument and description to function comment
+{
+ PCI_IO_DEVICE *Temp;
+
+ Temp = PciResNode->PciDev;
+
+ //
+ // Ensure the device is present
+ //
+ if (!Temp) {
+ return FALSE;
+ }
+
+ //
+ // PPB and RB should go ahead
+ //
+ if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {
+ return TRUE;
+ }
+
+ //
+ // Skip device on Bus0
+ //
+ if ((Temp->Parent) && (Temp->BusNumber == 0)) {
+ return FALSE;
+ }
+
+ //
+ // Skip VGA
+ //
+ if (IS_PCI_VGA (&Temp->Pci)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+PCI_RESOURCE_NODE *
+GetLargerConsumerDevice (
+ IN PCI_RESOURCE_NODE *PciResNode1,
+ IN PCI_RESOURCE_NODE *PciResNode2
+ )
+/*++
+
+Routine Description:
+
+ Get the larger resource consumer
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResNode1 - add argument and description to function comment
+// TODO: PciResNode2 - add argument and description to function comment
+{
+ if (!PciResNode2) {
+ return PciResNode1;
+ }
+
+ if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \
+ && (PciResNode2->ResourceUsage != PciResUsagePadding) )
+ {
+ return PciResNode1;
+ }
+
+ if (!PciResNode1) {
+ return PciResNode2;
+ }
+
+ if ((PciResNode1->Length) > (PciResNode2->Length)) {
+ return PciResNode1;
+ }
+
+ return PciResNode2;
+
+}
+
+PCI_RESOURCE_NODE *
+GetMaxResourceConsumerDevice (
+ IN PCI_RESOURCE_NODE *ResPool
+ )
+/*++
+
+Routine Description:
+
+ Get the max resource consumer in the host resource pool
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: ResPool - add argument and description to function comment
+{
+ PCI_RESOURCE_NODE *Temp;
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *PciResNode;
+ PCI_RESOURCE_NODE *PPBResNode;
+
+ PciResNode = NULL;
+
+ CurrentLink = ResPool->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &ResPool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (!IsRejectiveDevice (Temp)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \
+ && (Temp->ResourceUsage != PciResUsagePadding))
+ {
+ PPBResNode = GetMaxResourceConsumerDevice (Temp);
+ PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);
+ } else {
+ PciResNode = GetLargerConsumerDevice (PciResNode, Temp);
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return PciResNode;
+}
+
+EFI_STATUS
+PciHostBridgeAdjustAllocation (
+ IN PCI_RESOURCE_NODE *IoPool,
+ IN PCI_RESOURCE_NODE *Mem32Pool,
+ IN PCI_RESOURCE_NODE *PMem32Pool,
+ IN PCI_RESOURCE_NODE *Mem64Pool,
+ IN PCI_RESOURCE_NODE *PMem64Pool,
+ IN UINT64 IoResStatus,
+ IN UINT64 Mem32ResStatus,
+ IN UINT64 PMem32ResStatus,
+ IN UINT64 Mem64ResStatus,
+ IN UINT64 PMem64ResStatus
+ )
+/*++
+
+Routine Description:
+
+ Adjust host bridge allocation so as to reduce resource requirement
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: IoPool - add argument and description to function comment
+// TODO: Mem32Pool - add argument and description to function comment
+// TODO: PMem32Pool - add argument and description to function comment
+// TODO: Mem64Pool - add argument and description to function comment
+// TODO: PMem64Pool - add argument and description to function comment
+// TODO: IoResStatus - add argument and description to function comment
+// TODO: Mem32ResStatus - add argument and description to function comment
+// TODO: PMem32ResStatus - add argument and description to function comment
+// TODO: Mem64ResStatus - add argument and description to function comment
+// TODO: PMem64ResStatus - add argument and description to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+{
+ BOOLEAN AllocationAjusted;
+ PCI_RESOURCE_NODE *PciResNode;
+ PCI_RESOURCE_NODE *ResPool[5];
+ PCI_IO_DEVICE *RemovedPciDev[5];
+ UINT64 ResStatus[5];
+ UINTN RemovedPciDevNum;
+ UINTN DevIndex;
+ UINTN ResType;
+ EFI_STATUS Status;
+ REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;
+
+ PciResNode = NULL;
+ ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));
+ RemovedPciDevNum = 0;
+
+ ResPool[0] = IoPool;
+ ResPool[1] = Mem32Pool;
+ ResPool[2] = PMem32Pool;
+ ResPool[3] = Mem64Pool;
+ ResPool[4] = PMem64Pool;
+
+ ResStatus[0] = IoResStatus;
+ ResStatus[1] = Mem32ResStatus;
+ ResStatus[2] = PMem32ResStatus;
+ ResStatus[3] = Mem64ResStatus;
+ ResStatus[4] = PMem64ResStatus;
+
+ AllocationAjusted = FALSE;
+
+ for (ResType = 0; ResType < 5; ResType++) {
+
+ if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {
+ continue;
+ }
+
+ if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {
+ //
+ // Hostbridge hasn't this resource type
+ //
+ return EFI_ABORTED;
+ }
+
+ //
+ // Hostbridge hasn't enough resource
+ //
+ PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);
+ if (!PciResNode) {
+ continue;
+ }
+
+ //
+ // Check if the device has been removed before
+ //
+ for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {
+ if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {
+ continue;
+ }
+ }
+
+ //
+ // Remove the device if it isn't in the array
+ //
+ Status = RejectPciDevice (PciResNode->PciDev);
+ if (Status == EFI_SUCCESS) {
+
+ //
+ // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
+ //
+ //
+ // Have no way to get ReqRes, AllocRes & Bar here
+ //
+ ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));
+ AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;
+ AllocFailExtendedData.Bar = PciResNode->Bar;
+
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
+ (VOID *) &AllocFailExtendedData,
+ sizeof (AllocFailExtendedData)
+ );
+
+ //
+ // Add it to the array and indicate at least a device has been rejected
+ //
+ RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;
+ AllocationAjusted = TRUE;
+ }
+ }
+ //
+ // End for
+ //
+
+ if (AllocationAjusted) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_ABORTED;
+ }
+}
+
+EFI_STATUS
+ConstructAcpiResourceRequestor (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *IoNode,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node,
+ OUT VOID **pConfig
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: IoNode - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: pConfig - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT8 NumConfig;
+ UINT8 Aperture;
+ UINT8 *Configuration;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;
+
+ NumConfig = 0;
+ Aperture = 0;
+
+ *pConfig = NULL;
+
+ //
+ // if there is io request, add to the io aperture
+ //
+ if (ResourceRequestExisted (IoNode)) {
+ NumConfig++;
+ Aperture |= 0x01;
+ }
+
+ //
+ // if there is mem32 request, add to the mem32 aperture
+ //
+ if (ResourceRequestExisted (Mem32Node)) {
+ NumConfig++;
+ Aperture |= 0x02;
+ }
+
+ //
+ // if there is pmem32 request, add to the pmem32 aperture
+ //
+ if (ResourceRequestExisted (PMem32Node)) {
+ NumConfig++;
+ Aperture |= 0x04;
+ }
+
+ //
+ // if there is mem64 request, add to the mem64 aperture
+ //
+ if (ResourceRequestExisted (Mem64Node)) {
+ NumConfig++;
+ Aperture |= 0x08;
+ }
+
+ //
+ // if there is pmem64 request, add to the pmem64 aperture
+ //
+ if (ResourceRequestExisted (PMem64Node)) {
+ NumConfig++;
+ Aperture |= 0x10;
+ }
+
+ if (NumConfig != 0) {
+
+ //
+ // If there is at least one type of resource request,
+ // allocate a acpi resource node
+ //
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (Configuration == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (
+ Configuration,
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
+ );
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+
+ //
+ // Deal with io aperture
+ //
+ if (Aperture & 0x01) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ //
+ // Io
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+ //
+ // non ISA range
+ //
+ Ptr->SpecificFlag = 1;
+ Ptr->AddrLen = IoNode->Length;
+ Ptr->AddrRangeMax = IoNode->Alignment;
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+ //
+ // Deal with mem32 aperture
+ //
+ if (Aperture & 0x02) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // Nonprefechable
+ //
+ Ptr->SpecificFlag = 0;
+ //
+ // 32 bit
+ //
+ Ptr->AddrSpaceGranularity = 32;
+ Ptr->AddrLen = Mem32Node->Length;
+ Ptr->AddrRangeMax = Mem32Node->Alignment;
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+
+ //
+ // Deal with Pmem32 aperture
+ //
+ if (Aperture & 0x04) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // prefechable
+ //
+ Ptr->SpecificFlag = 0x6;
+ //
+ // 32 bit
+ //
+ Ptr->AddrSpaceGranularity = 32;
+ Ptr->AddrLen = PMem32Node->Length;
+ Ptr->AddrRangeMax = PMem32Node->Alignment;
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+ //
+ // Deal with mem64 aperture
+ //
+ if (Aperture & 0x08) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // nonprefechable
+ //
+ Ptr->SpecificFlag = 0;
+ //
+ // 64 bit
+ //
+ Ptr->AddrSpaceGranularity = 64;
+ Ptr->AddrLen = Mem64Node->Length;
+ Ptr->AddrRangeMax = Mem64Node->Alignment;
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+ //
+ // Deal with Pmem64 aperture
+ //
+ if (Aperture & 0x10) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // prefechable
+ //
+ Ptr->SpecificFlag = 0x06;
+ //
+ // 64 bit
+ //
+ Ptr->AddrSpaceGranularity = 64;
+ Ptr->AddrLen = PMem64Node->Length;
+ Ptr->AddrRangeMax = PMem64Node->Alignment;
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+
+ //
+ // put the checksum
+ //
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);
+
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
+ PtrEnd->Checksum = 0;
+
+ } else {
+
+ //
+ // If there is no resource request
+ //
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (Configuration == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
+ PtrEnd->Checksum = 0;
+ }
+
+ *pConfig = Configuration;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetResourceBase (
+ IN VOID *pConfig,
+ OUT UINT64 *IoBase,
+ OUT UINT64 *Mem32Base,
+ OUT UINT64 *PMem32Base,
+ OUT UINT64 *Mem64Base,
+ OUT UINT64 *PMem64Base
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: pConfig - add argument and description to function comment
+// TODO: IoBase - add argument and description to function comment
+// TODO: Mem32Base - add argument and description to function comment
+// TODO: PMem32Base - add argument and description to function comment
+// TODO: Mem64Base - add argument and description to function comment
+// TODO: PMem64Base - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT8 *Temp;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+ UINT64 ResStatus;
+
+ *IoBase = 0xFFFFFFFFFFFFFFFFULL;
+ *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;
+ *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;
+ *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;
+ *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;
+
+ Temp = (UINT8 *) pConfig;
+
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+ ResStatus = Ptr->AddrTranslationOffset;
+
+ if (ResStatus == EFI_RESOURCE_SATISFIED) {
+
+ switch (Ptr->ResType) {
+
+ //
+ // Memory type aperture
+ //
+ case 0:
+
+ //
+ // Check to see the granularity
+ //
+ if (Ptr->AddrSpaceGranularity == 32) {
+ if (Ptr->SpecificFlag & 0x06) {
+ *PMem32Base = Ptr->AddrRangeMin;
+ } else {
+ *Mem32Base = Ptr->AddrRangeMin;
+ }
+ }
+
+ if (Ptr->AddrSpaceGranularity == 64) {
+ if (Ptr->SpecificFlag & 0x06) {
+ *PMem64Base = Ptr->AddrRangeMin;
+ } else {
+ *Mem64Base = Ptr->AddrRangeMin;
+ }
+ }
+ break;
+
+ case 1:
+
+ //
+ // Io type aperture
+ //
+ *IoBase = Ptr->AddrRangeMin;
+ break;
+
+ default:
+ break;
+
+ }
+ //
+ // End switch
+ //
+ }
+ //
+ // End for
+ //
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciBridgeEnumerator (
+ IN PCI_IO_DEVICE *BridgeDev
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: BridgeDev - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT8 SubBusNumber;
+ UINT8 StartBusNumber;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+
+ SubBusNumber = 0;
+ StartBusNumber = 0;
+ PciIo = &(BridgeDev->PciIo);
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciAssignBusNumber (
+ BridgeDev,
+ StartBusNumber,
+ &SubBusNumber
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciBridgeResourceAllocator (BridgeDev);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = DetermineDeviceAttribute (BridgeDev);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+PciBridgeResourceAllocator (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_RESOURCE_NODE *IoBridge;
+ PCI_RESOURCE_NODE *Mem32Bridge;
+ PCI_RESOURCE_NODE *PMem32Bridge;
+ PCI_RESOURCE_NODE *Mem64Bridge;
+ PCI_RESOURCE_NODE *PMem64Bridge;
+ UINT64 IoBase;
+ UINT64 Mem32Base;
+ UINT64 PMem32Base;
+ UINT64 Mem64Base;
+ UINT64 PMem64Base;
+ EFI_STATUS Status;
+
+ IoBridge = CreateResourceNode (
+ Bridge,
+ 0,
+ 0xFFF,
+ 0,
+ PciBarTypeIo16,
+ PciResUsageTypical
+ );
+
+ Mem32Bridge = CreateResourceNode (
+ Bridge,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem32,
+ PciResUsageTypical
+ );
+
+ PMem32Bridge = CreateResourceNode (
+ Bridge,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem32,
+ PciResUsageTypical
+ );
+
+ Mem64Bridge = CreateResourceNode (
+ Bridge,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem64,
+ PciResUsageTypical
+ );
+
+ PMem64Bridge = CreateResourceNode (
+ Bridge,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem64,
+ PciResUsageTypical
+ );
+
+ //
+ // Create resourcemap by going through all the devices subject to this root bridge
+ //
+ Status = CreateResourceMap (
+ Bridge,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = GetResourceBaseFromBridge (
+ Bridge,
+ &IoBase,
+ &Mem32Base,
+ &PMem32Base,
+ &Mem64Base,
+ &PMem64Base
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Program IO resources
+ //
+ ProgramResource (
+ IoBase,
+ IoBridge
+ );
+
+ //
+ // Program Mem32 resources
+ //
+ ProgramResource (
+ Mem32Base,
+ Mem32Bridge
+ );
+
+ //
+ // Program PMem32 resources
+ //
+ ProgramResource (
+ PMem32Base,
+ PMem32Bridge
+ );
+
+ //
+ // Program Mem64 resources
+ //
+ ProgramResource (
+ Mem64Base,
+ Mem64Bridge
+ );
+
+ //
+ // Program PMem64 resources
+ //
+ ProgramResource (
+ PMem64Base,
+ PMem64Bridge
+ );
+
+ DestroyResourceTree (IoBridge);
+ DestroyResourceTree (Mem32Bridge);
+ DestroyResourceTree (PMem32Bridge);
+ DestroyResourceTree (PMem64Bridge);
+ DestroyResourceTree (Mem64Bridge);
+
+ gBS->FreePool (IoBridge);
+ gBS->FreePool (Mem32Bridge);
+ gBS->FreePool (PMem32Bridge);
+ gBS->FreePool (PMem64Bridge);
+ gBS->FreePool (Mem64Bridge);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetResourceBaseFromBridge (
+ IN PCI_IO_DEVICE *Bridge,
+ OUT UINT64 *IoBase,
+ OUT UINT64 *Mem32Base,
+ OUT UINT64 *PMem32Base,
+ OUT UINT64 *Mem64Base,
+ OUT UINT64 *PMem64Base
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: IoBase - add argument and description to function comment
+// TODO: Mem32Base - add argument and description to function comment
+// TODO: PMem32Base - add argument and description to function comment
+// TODO: Mem64Base - add argument and description to function comment
+// TODO: PMem64Base - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ if (!Bridge->Allocated) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *IoBase = gAllOne;
+ *Mem32Base = gAllOne;
+ *PMem32Base = gAllOne;
+ *Mem64Base = gAllOne;
+ *PMem64Base = gAllOne;
+
+ if (IS_PCI_BRIDGE (&Bridge->Pci)) {
+
+ if (Bridge->PciBar[PPB_IO_RANGE].Length) {
+ *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;
+ }
+
+ if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {
+ *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;
+ }
+
+ if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {
+ *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;
+ }
+
+ if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {
+ *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;
+ } else {
+ *PMem64Base = gAllOne;
+ }
+
+ }
+
+ if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {
+ if (Bridge->PciBar[P2C_IO_1].Length) {
+ *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;
+ } else {
+ if (Bridge->PciBar[P2C_IO_2].Length) {
+ *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;
+ }
+ }
+
+ if (Bridge->PciBar[P2C_MEM_1].Length) {
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {
+ *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
+ }
+
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {
+ *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
+ }
+ }
+
+ if (Bridge->PciBar[P2C_MEM_2].Length) {
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {
+ *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
+ }
+
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {
+ *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NotifyPhase (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: Phase - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE HostBridgeHandle;
+ EFI_HANDLE RootBridgeHandle;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_STATUS Status;
+
+ HostBridgeHandle = NULL;
+ RootBridgeHandle = NULL;
+ if (gPciPlatformProtocol != NULL) {
+ //
+ // Get Host Bridge Handle.
+ //
+ PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);
+
+ //
+ // Get the rootbridge Io protocol to find the host bridge handle
+ //
+ Status = gBS->HandleProtocol (
+ RootBridgeHandle,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;
+
+ //
+ // Call PlatformPci::PhaseNotify() if the protocol is present.
+ //
+ gPciPlatformProtocol->PhaseNotify (
+ gPciPlatformProtocol,
+ HostBridgeHandle,
+ Phase,
+ ChipsetEntry
+ );
+ }
+
+ Status = PciResAlloc->NotifyPhase (
+ PciResAlloc,
+ Phase
+ );
+
+ if (gPciPlatformProtocol != NULL) {
+ //
+ // Call PlatformPci::PhaseNotify() if the protocol is present.
+ //
+ gPciPlatformProtocol->PhaseNotify (
+ gPciPlatformProtocol,
+ HostBridgeHandle,
+ Phase,
+ ChipsetExit
+ );
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PreprocessController (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Func,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+// TODO: Phase - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;
+ EFI_HANDLE RootBridgeHandle;
+ EFI_HANDLE HostBridgeHandle;
+ EFI_STATUS Status;
+
+ //
+ // Get the host bridge handle
+ //
+ HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;
+
+ //
+ // Get the pci host bridge resource allocation protocol
+ //
+ Status = gBS->OpenProtocol (
+ HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+ (VOID **) &PciResAlloc,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get Root Brige Handle
+ //
+ while (Bridge->Parent) {
+ Bridge = Bridge->Parent;
+ }
+
+ RootBridgeHandle = Bridge->Handle;
+
+ RootBridgePciAddress.Register = 0;
+ RootBridgePciAddress.Function = Func;
+ RootBridgePciAddress.Device = Device;
+ RootBridgePciAddress.Bus = Bus;
+ RootBridgePciAddress.ExtendedRegister = 0;
+
+ if (gPciPlatformProtocol != NULL) {
+ //
+ // Call PlatformPci::PrepController() if the protocol is present.
+ //
+ gPciPlatformProtocol->PlatformPrepController (
+ gPciPlatformProtocol,
+ HostBridgeHandle,
+ RootBridgeHandle,
+ RootBridgePciAddress,
+ Phase,
+ ChipsetEntry
+ );
+ }
+
+ Status = PciResAlloc->PreprocessController (
+ PciResAlloc,
+ RootBridgeHandle,
+ RootBridgePciAddress,
+ Phase
+ );
+
+ if (gPciPlatformProtocol != NULL) {
+ //
+ // Call PlatformPci::PrepController() if the protocol is present.
+ //
+ gPciPlatformProtocol->PlatformPrepController (
+ gPciPlatformProtocol,
+ HostBridgeHandle,
+ RootBridgeHandle,
+ RootBridgePciAddress,
+ Phase,
+ ChipsetExit
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciHotPlugRequestNotify (
+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,
+ IN EFI_PCI_HOTPLUG_OPERATION Operation,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,
+ IN OUT UINT8 *NumberOfChildren,
+ IN OUT EFI_HANDLE * ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ Hot plug request notify.
+
+Arguments:
+
+ This - A pointer to the hot plug request protocol.
+ Operation - The operation.
+ Controller - A pointer to the controller.
+ RemainningDevicePath - A pointer to the device path.
+ NumberOfChildren - A the number of child handle in the ChildHandleBuffer.
+ ChildHandleBuffer - A pointer to the array contain the child handle.
+
+Returns:
+
+ Status code.
+
+--*/
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Bridge;
+ PCI_IO_DEVICE *Temp;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Index;
+ EFI_HANDLE RootBridgeHandle;
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
+
+ //
+ // Get root bridge handle
+ //
+ Temp = Bridge;
+ while (Temp->Parent) {
+ Temp = Temp->Parent;
+ }
+
+ RootBridgeHandle = Temp->Handle;
+
+ if (Operation == EfiPciHotPlugRequestAdd) {
+
+ if (NumberOfChildren != NULL) {
+ *NumberOfChildren = 0;
+ }
+
+ if (IsListEmpty (&Bridge->ChildList)) {
+
+ Status = PciBridgeEnumerator (Bridge);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ Status = StartPciDevicesOnBridge (
+ RootBridgeHandle,
+ Bridge,
+ RemainingDevicePath,
+ NumberOfChildren,
+ ChildHandleBuffer
+ );
+
+ return EFI_SUCCESS;
+ }
+
+ if (Operation == EfiPciHotplugRequestRemove) {
+
+ if (*NumberOfChildren == 0) {
+ //
+ // Remove all devices on the bridge
+ //
+ Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);
+ return Status;
+
+ }
+
+ for (Index = 0; Index < *NumberOfChildren; Index++) {
+ //
+ // De register all the pci device
+ //
+ Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ }
+ //
+ // End for
+ //
+ return EFI_SUCCESS;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+SearchHostBridgeHandle (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: RootBridgeHandle - add argument and description to function comment
+{
+ EFI_HANDLE HostBridgeHandle;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ UINTN Index;
+ EFI_STATUS Status;
+
+ //
+ // Get the rootbridge Io protocol to find the host bridge handle
+ //
+ Status = gBS->OpenProtocol (
+ RootBridgeHandle,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ RootBridgeHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+AddHostBridgeEnumerator (
+ IN EFI_HANDLE HostBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: HostBridgeHandle - add argument and description to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+// TODO: EFI_ABORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINTN Index;
+
+ if (!HostBridgeHandle) {
+ return EFI_ABORTED;
+ }
+
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
+ return EFI_ABORTED;
+ }
+ }
+
+ if (Index < PCI_MAX_HOST_BRIDGE_NUM) {
+ gPciHostBrigeHandles[Index] = HostBridgeHandle;
+ gPciHostBridgeNumber++;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h new file mode 100644 index 0000000000..e7667d5c49 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h @@ -0,0 +1,628 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciEnumerator.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ENUMERATOR_H
+#define _EFI_PCI_ENUMERATOR_H
+
+#include "PciResourceSupport.h"
+
+EFI_STATUS
+PciEnumerator (
+ IN EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciRootBridgeEnumerator (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+ RootBridgeDev - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProcessOptionRom (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT64 RomBase,
+ IN UINT64 MaxLength
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ RomBase - TODO: add argument description
+ MaxLength - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciAssignBusNumber (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ StartBusNumber - TODO: add argument description
+ SubBusNumber - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DetermineRootBridgeAttributes (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+ RootBridgeDev - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+UINT64
+GetMaxOptionRomSize (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeDeviceAttribute (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourceAllocationStatus (
+ VOID *AcpiConfig,
+ OUT UINT64 *IoResStatus,
+ OUT UINT64 *Mem32ResStatus,
+ OUT UINT64 *PMem32ResStatus,
+ OUT UINT64 *Mem64ResStatus,
+ OUT UINT64 *PMem64ResStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ AcpiConfig - TODO: add argument description
+ IoResStatus - TODO: add argument description
+ Mem32ResStatus - TODO: add argument description
+ PMem32ResStatus - TODO: add argument description
+ Mem64ResStatus - TODO: add argument description
+ PMem64ResStatus - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RejectPciDevice (
+ IN PCI_IO_DEVICE *PciDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsRejectiveDevice (
+ IN PCI_RESOURCE_NODE *PciResNode
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResNode - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_RESOURCE_NODE *
+GetLargerConsumerDevice (
+ IN PCI_RESOURCE_NODE *PciResNode1,
+ IN PCI_RESOURCE_NODE *PciResNode2
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResNode1 - TODO: add argument description
+ PciResNode2 - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_RESOURCE_NODE *
+GetMaxResourceConsumerDevice (
+ IN PCI_RESOURCE_NODE *ResPool
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ResPool - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeAdjustAllocation (
+ IN PCI_RESOURCE_NODE *IoPool,
+ IN PCI_RESOURCE_NODE *Mem32Pool,
+ IN PCI_RESOURCE_NODE *PMem32Pool,
+ IN PCI_RESOURCE_NODE *Mem64Pool,
+ IN PCI_RESOURCE_NODE *PMem64Pool,
+ IN UINT64 IoResStatus,
+ IN UINT64 Mem32ResStatus,
+ IN UINT64 PMem32ResStatus,
+ IN UINT64 Mem64ResStatus,
+ IN UINT64 PMem64ResStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ IoPool - TODO: add argument description
+ Mem32Pool - TODO: add argument description
+ PMem32Pool - TODO: add argument description
+ Mem64Pool - TODO: add argument description
+ PMem64Pool - TODO: add argument description
+ IoResStatus - TODO: add argument description
+ Mem32ResStatus - TODO: add argument description
+ PMem32ResStatus - TODO: add argument description
+ Mem64ResStatus - TODO: add argument description
+ PMem64ResStatus - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ConstructAcpiResourceRequestor (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *IoNode,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node,
+ OUT VOID **pConfig
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+ pConfig - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourceBase (
+ IN VOID *pConfig,
+ OUT UINT64 *IoBase,
+ OUT UINT64 *Mem32Base,
+ OUT UINT64 *PMem32Base,
+ OUT UINT64 *Mem64Base,
+ OUT UINT64 *PMem64Base
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ pConfig - TODO: add argument description
+ IoBase - TODO: add argument description
+ Mem32Base - TODO: add argument description
+ PMem32Base - TODO: add argument description
+ Mem64Base - TODO: add argument description
+ PMem64Base - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciBridgeEnumerator (
+ IN PCI_IO_DEVICE *BridgeDev
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ BridgeDev - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciBridgeResourceAllocator (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourceBaseFromBridge (
+ IN PCI_IO_DEVICE *Bridge,
+ OUT UINT64 *IoBase,
+ OUT UINT64 *Mem32Base,
+ OUT UINT64 *PMem32Base,
+ OUT UINT64 *Mem64Base,
+ OUT UINT64 *PMem64Base
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ IoBase - TODO: add argument description
+ Mem32Base - TODO: add argument description
+ PMem32Base - TODO: add argument description
+ Mem64Base - TODO: add argument description
+ PMem64Base - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeP2CProcess (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+NotifyPhase (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+ Phase - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PreprocessController (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Func,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+ Phase - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciHotPlugRequestNotify (
+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,
+ IN EFI_PCI_HOTPLUG_OPERATION Operation,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,
+ IN OUT UINT8 *NumberOfChildren,
+ IN OUT EFI_HANDLE * ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Operation - TODO: add argument description
+ Controller - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+SearchHostBridgeHandle (
+ IN EFI_HANDLE RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+AddHostBridgeEnumerator (
+ IN EFI_HANDLE HostBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HostBridgeHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c new file mode 100644 index 0000000000..2c54897953 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c @@ -0,0 +1,2261 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciEnumeratorSupport.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+#include "PciEnumeratorSupport.h"
+#include "PciCommand.h"
+#include "PciIo.h"
+
+EFI_STATUS
+PciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to check whether the pci device is present
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ UINT64 Address;
+ EFI_STATUS Status;
+
+ //
+ // Create PCI address map in terms of Bus, Device and Func
+ //
+ Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+ //
+ // Read the Vendor Id register
+ //
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ Pci
+ );
+
+ if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {
+
+ //
+ // Read the entire config header for the device
+ //
+
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ sizeof (PCI_TYPE00) / sizeof (UINT32),
+ Pci
+ );
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+PciPciDeviceInfoCollector (
+ IN PCI_IO_DEVICE *Bridge,
+ UINT8 StartBusNumber
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: StartBusNumber - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_TYPE00 Pci;
+ UINT8 Device;
+ UINT8 Func;
+ UINT8 SecBus;
+ PCI_IO_DEVICE *PciIoDevice;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ Status = EFI_SUCCESS;
+ SecBus = 0;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+ //
+ // Check to see whether PCI device is present
+ //
+
+ Status = PciDevicePresent (
+ Bridge->PciRootBridgeIo,
+ &Pci,
+ (UINT8) StartBusNumber,
+ (UINT8) Device,
+ (UINT8) Func
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Call back to host bridge function
+ //
+ PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);
+
+ //
+ // Collect all the information about the PCI device discovered
+ //
+ Status = PciSearchDevice (
+ Bridge,
+ &Pci,
+ (UINT8) StartBusNumber,
+ Device,
+ Func,
+ &PciIoDevice
+ );
+
+ //
+ // Recursively scan PCI busses on the other side of PCI-PCI bridges
+ //
+ //
+
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {
+
+ //
+ // If it is PPB, we need to get the secondary bus to continue the enumeration
+ //
+ PciIo = &(PciIoDevice->PciIo);
+
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get resource padding for PPB
+ //
+ GetResourcePaddingPpb (PciIoDevice);
+
+ //
+ // Deep enumerate the next level bus
+ //
+ Status = PciPciDeviceInfoCollector (
+ PciIoDevice,
+ (UINT8) (SecBus)
+ );
+
+ }
+
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+ }
+
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciSearchDevice (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Func,
+ OUT PCI_IO_DEVICE **PciDevice
+ )
+/*++
+
+Routine Description:
+
+ Search required device.
+
+Arguments:
+
+ Bridge - A pointer to the PCI_IO_DEVICE.
+ Pci - A pointer to the PCI_TYPE00.
+ Bus - Bus number.
+ Device - Device number.
+ Func - Function number.
+ PciDevice - The Required pci device.
+
+Returns:
+
+ Status code.
+
+--*/
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = NULL;
+
+ if (!IS_PCI_BRIDGE (Pci)) {
+
+ if (IS_CARDBUS_BRIDGE (Pci)) {
+ PciIoDevice = GatherP2CInfo (
+ Bridge,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+ if (gFullEnumeration) {
+ InitializeP2C (PciIoDevice);
+ }
+ } else {
+
+ //
+ // Create private data for Pci Device
+ //
+ PciIoDevice = GatherDeviceInfo (
+ Bridge,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+
+ }
+
+ } else {
+
+ //
+ // Create private data for PPB
+ //
+ PciIoDevice = GatherPpbInfo (
+ Bridge,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+
+ //
+ // Special initialization for PPB including making the PPB quiet
+ //
+ if (gFullEnumeration) {
+ InitializePpb (PciIoDevice);
+ }
+ }
+
+ if (!PciIoDevice) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Update the bar information for this PCI device so as to support some specific device
+ //
+ UpdatePciInfo (PciIoDevice);
+
+ if (PciIoDevice->DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Detect this function has option rom
+ //
+ if (gFullEnumeration) {
+
+ if (!IS_CARDBUS_BRIDGE (Pci)) {
+
+ GetOpRomInfo (PciIoDevice);
+
+ }
+
+ ResetPowerManagementFeature (PciIoDevice);
+
+ }
+
+ //
+ // Insert it into a global tree for future reference
+ //
+ InsertPciDevice (Bridge, PciIoDevice);
+
+ //
+ // Determine PCI device attributes
+ //
+
+ if (PciDevice != NULL) {
+ *PciDevice = PciIoDevice;
+ }
+
+ return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+GatherDeviceInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+{
+ UINTN Offset;
+ UINTN BarIndex;
+ PCI_IO_DEVICE *PciIoDevice;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+ PciIoDevice = CreatePciIoDevice (
+ PciRootBridgeIo,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+
+ if (!PciIoDevice) {
+ return NULL;
+ }
+
+ //
+ // Create a device path for this PCI device and store it into its private data
+ //
+ CreatePciDevicePath (
+ Bridge->DevicePath,
+ PciIoDevice
+ );
+
+ //
+ // If it is a full enumeration, disconnect the device in advance
+ //
+ if (gFullEnumeration) {
+
+ PciSetCommandRegister (PciIoDevice, 0);
+
+ }
+
+ //
+ // Start to parse the bars
+ //
+ for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {
+ Offset = PciParseBar (PciIoDevice, Offset, BarIndex);
+ }
+
+ return PciIoDevice;
+}
+
+PCI_IO_DEVICE *
+GatherPpbInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+{
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ PCI_IO_DEVICE *PciIoDevice;
+ EFI_STATUS Status;
+ UINT32 Value;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 Temp;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+ PciIoDevice = CreatePciIoDevice (
+ PciRootBridgeIo,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+
+ if (!PciIoDevice) {
+ return NULL;
+ }
+
+ //
+ // Create a device path for this PCI device and store it into its private data
+ //
+ CreatePciDevicePath (
+ Bridge->DevicePath,
+ PciIoDevice
+ );
+
+ if (gFullEnumeration) {
+ PciSetCommandRegister (PciIoDevice, 0);
+
+ //
+ // Initalize the bridge control register
+ //
+ PciSetBridgeControlRegister (PciIoDevice, 0);
+
+ }
+
+ //
+ // PPB can have two BARs
+ //
+ if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {
+ //
+ // Not 64-bit bar
+ //
+ PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);
+ }
+
+ PciIo = &PciIoDevice->PciIo;
+
+ //
+ // Test whether it support 32 decode or not
+ //
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);
+
+ if (Value) {
+ if (Value & 0x01) {
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;
+ } else {
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;
+ }
+ }
+
+ Status = BarExisted (
+ PciIoDevice,
+ 0x24,
+ NULL,
+ NULL
+ );
+
+ //
+ // test if it supports 64 memory or not
+ //
+ if (!EFI_ERROR (Status)) {
+
+ Status = BarExisted (
+ PciIoDevice,
+ 0x28,
+ NULL,
+ NULL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
+ } else {
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
+ }
+ }
+
+ //
+ // Memory 32 code is required for ppb
+ //
+ PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;
+
+ GetResourcePaddingPpb (PciIoDevice);
+
+ return PciIoDevice;
+}
+
+PCI_IO_DEVICE *
+GatherP2CInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+{
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+ PciIoDevice = CreatePciIoDevice (
+ PciRootBridgeIo,
+ Pci,
+ Bus,
+ Device,
+ Func
+ );
+
+ if (!PciIoDevice) {
+ return NULL;
+ }
+
+ //
+ // Create a device path for this PCI device and store it into its private data
+ //
+ CreatePciDevicePath (
+ Bridge->DevicePath,
+ PciIoDevice
+ );
+
+ if (gFullEnumeration) {
+ PciSetCommandRegister (PciIoDevice, 0);
+
+ //
+ // Initalize the bridge control register
+ //
+ PciSetBridgeControlRegister (PciIoDevice, 0);
+
+ }
+ //
+ // P2C only has one bar that is in 0x10
+ //
+ PciParseBar (PciIoDevice, 0x10, P2C_BAR_0);
+
+ //
+ // Read PciBar information from the bar register
+ //
+ GetBackPcCardBar (PciIoDevice);
+ PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |
+ EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |
+ EFI_BRIDGE_IO32_DECODE_SUPPORTED;
+
+ return PciIoDevice;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreatePciDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: ParentDevicePath - add argument and description to function comment
+// TODO: PciIoDevice - add argument and description to function comment
+{
+
+ PCI_DEVICE_PATH PciNode;
+
+ //
+ // Create PCI device path
+ //
+ PciNode.Header.Type = HARDWARE_DEVICE_PATH;
+ PciNode.Header.SubType = HW_PCI_DP;
+ SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
+
+ PciNode.Device = PciIoDevice->DeviceNumber;
+ PciNode.Function = PciIoDevice->FunctionNumber;
+ PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);
+
+ return PciIoDevice->DevicePath;
+}
+
+EFI_STATUS
+BarExisted (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Offset,
+ OUT UINT32 *BarLengthValue,
+ OUT UINT32 *OriginalBarValue
+ )
+/*++
+
+Routine Description:
+
+ Check the bar is existed or not.
+
+Arguments:
+
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+ Offset - The offset.
+ BarLengthValue - The bar length value.
+ OriginalBarValue - The original bar value.
+
+Returns:
+
+ EFI_NOT_FOUND - The bar don't exist.
+ EFI_SUCCESS - The bar exist.
+
+--*/
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT32 OriginalValue;
+ UINT32 Value;
+ EFI_TPL OldTpl;
+
+ PciIo = &PciIoDevice->PciIo;
+
+ //
+ // Preserve the original value
+ //
+
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);
+
+ //
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);
+
+ //
+ // Write back the original value
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);
+
+ //
+ // Restore TPL to its original level
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ if (BarLengthValue != NULL) {
+ *BarLengthValue = Value;
+ }
+
+ if (OriginalBarValue != NULL) {
+ *OriginalBarValue = OriginalValue;
+ }
+
+ if (Value == 0) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+PciTestSupportedAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 *Command,
+ IN UINT16 *BridgeControl,
+ IN UINT16 *OldCommand,
+ IN UINT16 *OldBridgeControl
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Command - add argument and description to function comment
+// TODO: BridgeControl - add argument and description to function comment
+// TODO: OldCommand - add argument and description to function comment
+// TODO: OldBridgeControl - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_TPL OldTpl;
+
+ //
+ // Preserve the original value
+ //
+ PciReadCommandRegister (PciIoDevice, OldCommand);
+
+ //
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
+
+ PciSetCommandRegister (PciIoDevice, *Command);
+ PciReadCommandRegister (PciIoDevice, Command);
+
+ //
+ // Write back the original value
+ //
+ PciSetCommandRegister (PciIoDevice, *OldCommand);
+
+ //
+ // Restore TPL to its original level
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+
+ //
+ // Preserve the original value
+ //
+ PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);
+
+ //
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed
+ //
+ OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
+
+ PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);
+ PciReadBridgeControlRegister (PciIoDevice, BridgeControl);
+
+ //
+ // Write back the original value
+ //
+ PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);
+
+ //
+ // Restore TPL to its original level
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ } else {
+ *OldBridgeControl = 0;
+ *BridgeControl = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciSetDeviceAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 Command,
+ IN UINT16 BridgeControl,
+ IN UINTN Option
+ )
+/*++
+
+ Routine Description:
+ Set the supported or current attributes of a PCI device
+
+ Arguments:
+ PciIoDevice - Structure pointer for PCI device.
+ Command - Command register value.
+ BridgeControl - Bridge control value for PPB or P2C.
+ Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.
+
+ Returns:
+
+--*/
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+
+Returns:
+
+ EFI_SUCCESS Always success
+
+
+--*/
+{
+ UINT64 Attributes;
+
+ Attributes = 0;
+
+ if (Command & EFI_PCI_COMMAND_IO_SPACE) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;
+ }
+
+ if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;
+ }
+
+ if (Command & EFI_PCI_COMMAND_BUS_MASTER) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
+ }
+
+ if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+ }
+
+ if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
+ }
+
+ if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+ }
+
+ if (Option == EFI_SET_SUPPORTS) {
+
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
+ }
+
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+ //
+ // For bridge, it should support IDE attributes
+ //
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;
+ } else {
+
+ if (IS_PCI_IDE (&PciIoDevice->Pci)) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;
+ }
+
+ if (IS_PCI_VGA (&PciIoDevice->Pci)) {
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
+ }
+ }
+
+ PciIoDevice->Supports = Attributes;
+ PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \
+ EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );
+
+ } else {
+ PciIoDevice->Attributes = Attributes;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFastBackToBackSupport (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT8 StatusIndex
+ )
+/*++
+
+Routine Description:
+
+ Determine if the device can support Fast Back to Back attribute
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: StatusIndex - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ UINT32 StatusRegister;
+
+ //
+ // Read the status register
+ //
+ PciIo = &PciIoDevice->PciIo;
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check the Fast B2B bit
+ //
+ if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+}
+
+EFI_STATUS
+ProcessOptionRomLight (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Process the option ROM for all the children of the specified parent PCI device.
+ It can only be used after the first full Option ROM process.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Temp;
+ LIST_ENTRY *CurrentLink;
+
+ //
+ // For RootBridge, PPB , P2C, go recursively to traverse all its children
+ //
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ ProcessOptionRomLight (Temp);
+ }
+
+ PciRomGetImageMapping (Temp);
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DetermineDeviceAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Determine the related attributes of all devices under a Root Bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT16 Command;
+ UINT16 BridgeControl;
+ UINT16 OldCommand;
+ UINT16 OldBridgeControl;
+ BOOLEAN FastB2BSupport;
+
+ /*
+ UINT8 IdePI;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ */
+ PCI_IO_DEVICE *Temp;
+ LIST_ENTRY *CurrentLink;
+ EFI_STATUS Status;
+
+ //
+ // For Root Bridge, just copy it by RootBridgeIo proctocol
+ // so as to keep consistent with the actual attribute
+ //
+ if (!PciIoDevice->Parent) {
+ Status = PciIoDevice->PciRootBridgeIo->GetAttributes (
+ PciIoDevice->PciRootBridgeIo,
+ &PciIoDevice->Supports,
+ &PciIoDevice->Attributes
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+
+ //
+ // Set the attributes to be checked for common PCI devices and PPB or P2C
+ // Since some devices only support part of them, it is better to set the
+ // attribute according to its command or bridge control register
+ //
+ Command = EFI_PCI_COMMAND_IO_SPACE |
+ EFI_PCI_COMMAND_MEMORY_SPACE |
+ EFI_PCI_COMMAND_BUS_MASTER |
+ EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+
+ BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA;
+
+ //
+ // Test whether the device can support attributes above
+ //
+ PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);
+
+ //
+ // Set the supported attributes for specified PCI device
+ //
+ PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);
+
+ //
+ // Set the current attributes for specified PCI device
+ //
+ PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);
+
+ //
+ // Enable other supported attributes but not defined in PCI_IO_PROTOCOL
+ //
+ PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);
+
+ //
+ // Enable IDE native mode
+ //
+ /*
+ if (IS_PCI_IDE(&PciIoDevice->Pci)) {
+
+ PciIo = &PciIoDevice->PciIo;
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0x09,
+ 1,
+ &IdePI
+ );
+
+ //
+ // Set native mode if it can be supported
+ //
+ IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0x09,
+ 1,
+ &IdePI
+ );
+
+ }
+ */
+ }
+
+ FastB2BSupport = TRUE;
+
+ //
+ // P2C can not support FB2B on the secondary side
+ //
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+ FastB2BSupport = FALSE;
+ }
+
+ //
+ // For RootBridge, PPB , P2C, go recursively to traverse all its children
+ //
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ Status = DetermineDeviceAttribute (Temp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Detect Fast Bact to Bact support for the device under the bridge
+ //
+ Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);
+ if (FastB2BSupport && EFI_ERROR (Status)) {
+ FastB2BSupport = FALSE;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+ //
+ // Set or clear Fast Back to Back bit for the whole bridge
+ //
+ if (!IsListEmpty (&PciIoDevice->ChildList)) {
+
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
+
+ Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);
+
+ if (EFI_ERROR (Status) || (!FastB2BSupport)) {
+ FastB2BSupport = FALSE;
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);
+ } else {
+ PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);
+ }
+ }
+
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+ if (FastB2BSupport) {
+ PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);
+ } else {
+ PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+ }
+ //
+ // End for IsListEmpty
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdatePciInfo (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to update the bar information for those incompatible PCI device
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ UINTN BarIndex;
+ UINTN BarEndIndex;
+ BOOLEAN SetFlag;
+ VOID *Configuration;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+
+ Configuration = NULL;
+
+ //
+ // It can only be supported after the Incompatible PCI Device
+ // Support Protocol has been installed
+ //
+ if (gEfiIncompatiblePciDeviceSupport == NULL) {
+
+ Status = gBS->LocateProtocol (
+ &gEfiIncompatiblePciDeviceSupportProtocolGuid,
+ NULL,
+ (VOID **) &gEfiIncompatiblePciDeviceSupport
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Check whether the device belongs to incompatible devices or not
+ // If it is , then get its special requirement in the ACPI table
+ //
+ Status = gEfiIncompatiblePciDeviceSupport->CheckDevice (
+ gEfiIncompatiblePciDeviceSupport,
+ PciIoDevice->Pci.Hdr.VendorId,
+ PciIoDevice->Pci.Hdr.DeviceId,
+ PciIoDevice->Pci.Hdr.RevisionID,
+ PciIoDevice->Pci.Device.SubsystemVendorID,
+ PciIoDevice->Pci.Device.SubsystemID,
+ &Configuration
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update PCI device information from the ACPI table
+ //
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+
+ while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {
+
+ if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ //
+ // The format is not support
+ //
+ break;
+ }
+
+ BarIndex = (UINTN) Ptr->AddrTranslationOffset;
+ BarEndIndex = BarIndex;
+
+ //
+ // Update all the bars in the device
+ //
+ if (BarIndex == PCI_BAR_ALL) {
+ BarIndex = 0;
+ BarEndIndex = PCI_MAX_BAR - 1;
+ }
+
+ if (BarIndex >= PCI_MAX_BAR) {
+ Ptr++;
+ continue;
+ }
+
+ for (; BarIndex <= BarEndIndex; BarIndex++) {
+ SetFlag = FALSE;
+ switch (Ptr->ResType) {
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:
+
+ //
+ // Make sure the bar is memory type
+ //
+ if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {
+ SetFlag = TRUE;
+ }
+ break;
+
+ case ACPI_ADDRESS_SPACE_TYPE_IO:
+
+ //
+ // Make sure the bar is IO type
+ //
+ if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {
+ SetFlag = TRUE;
+ }
+ break;
+ }
+
+ if (SetFlag) {
+
+ //
+ // Update the new alignment for the device
+ //
+ SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax);
+
+ //
+ // Update the new length for the device
+ //
+ if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {
+ PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;
+ }
+ }
+ }
+
+ Ptr++;
+ }
+
+ gBS->FreePool (Configuration);
+ return Status;
+
+}
+
+VOID
+SetNewAlign (
+ IN UINT64 *Alignment,
+ IN UINT64 NewAlignment
+ )
+/*++
+
+Routine Description:
+
+ This routine will update the alignment with the new alignment
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Alignment - add argument and description to function comment
+// TODO: NewAlignment - add argument and description to function comment
+{
+ UINT64 OldAlignment;
+ UINTN ShiftBit;
+
+ //
+ // The new alignment is the same as the original,
+ // so skip it
+ //
+ if (NewAlignment == PCI_BAR_OLD_ALIGN) {
+ return ;
+ }
+ //
+ // Check the validity of the parameter
+ //
+ if (NewAlignment != PCI_BAR_EVEN_ALIGN &&
+ NewAlignment != PCI_BAR_SQUAD_ALIGN &&
+ NewAlignment != PCI_BAR_DQUAD_ALIGN ) {
+ *Alignment = NewAlignment;
+ return ;
+ }
+
+ OldAlignment = (*Alignment) + 1;
+ ShiftBit = 0;
+
+ //
+ // Get the first non-zero hex value of the length
+ //
+ while ((OldAlignment & 0x0F) == 0x00) {
+ OldAlignment = RShiftU64 (OldAlignment, 4);
+ ShiftBit += 4;
+ }
+
+ //
+ // Adjust the alignment to even, quad or double quad boundary
+ //
+ if (NewAlignment == PCI_BAR_EVEN_ALIGN) {
+ if (OldAlignment & 0x01) {
+ OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);
+ }
+ } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {
+ if (OldAlignment & 0x03) {
+ OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);
+ }
+ } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {
+ if (OldAlignment & 0x07) {
+ OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);
+ }
+ }
+
+ //
+ // Update the old value
+ //
+ NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;
+ *Alignment = NewAlignment;
+
+ return ;
+}
+
+UINTN
+PciParseBar (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Offset,
+ IN UINTN BarIndex
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+{
+ UINT32 Value;
+ UINT64 BarValue64;
+ UINT32 OriginalValue;
+ UINT32 Mask;
+ UINT32 Data;
+ UINT8 Index;
+ EFI_STATUS Status;
+
+ OriginalValue = 0;
+ Value = 0;
+ BarValue64 = 0;
+
+ Status = BarExisted (
+ PciIoDevice,
+ Offset,
+ &Value,
+ &OriginalValue
+ );
+
+ if (EFI_ERROR (Status)) {
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;
+ PciIoDevice->PciBar[BarIndex].Length = 0;
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;
+
+ //
+ // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
+ //
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;
+ return Offset + 4;
+ }
+
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;
+ if (Value & 0x01) {
+ //
+ // Device I/Os
+ //
+ Mask = 0xfffffffc;
+
+ if (Value & 0xFFFF0000) {
+ //
+ // It is a IO32 bar
+ //
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;
+ PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ } else {
+ //
+ // It is a IO16 bar
+ //
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;
+ PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ }
+ //
+ // Workaround. Some platforms inplement IO bar with 0 length
+ // Need to treat it as no-bar
+ //
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {
+ PciIoDevice->PciBar[BarIndex].BarType = 0;
+ }
+
+ PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;
+
+ } else {
+
+ Mask = 0xfffffff0;
+
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;
+
+ switch (Value & 0x07) {
+
+ //
+ //memory space; anywhere in 32 bit address space
+ //
+ case 0x00:
+ if (Value & 0x08) {
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;
+ } else {
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;
+ }
+
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ break;
+
+ //
+ // memory space; anywhere in 64 bit address space
+ //
+ case 0x04:
+ if (Value & 0x08) {
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;
+ } else {
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;
+ }
+
+ //
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
+ // is regarded as an extension for the first bar. As a result
+ // the sizing will be conducted on combined 64 bit value
+ // Here just store the masked first 32bit value for future size
+ // calculation
+ //
+ PciIoDevice->PciBar[BarIndex].Length = Value & Mask;
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ //
+ // Increment the offset to point to next DWORD
+ //
+ Offset += 4;
+
+ Status = BarExisted (
+ PciIoDevice,
+ Offset,
+ &Value,
+ &OriginalValue
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Offset + 4;
+ }
+
+ //
+ // Fix the length to support some spefic 64 bit BAR
+ //
+ Data = Value;
+ Index = 0;
+ for (Data = Value; Data != 0; Data >>= 1) {
+ Index ++;
+ }
+ Value |= ((UINT32)(-1) << Index);
+
+ //
+ // Calculate the size of 64bit bar
+ //
+ PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);
+
+ PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);
+ PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ break;
+
+ //
+ // reserved
+ //
+ default:
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
+
+ break;
+ }
+ }
+
+ //
+ // Check the length again so as to keep compatible with some special bars
+ //
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;
+ }
+
+ //
+ // Increment number of bar
+ //
+ return Offset + 4;
+}
+
+EFI_STATUS
+InitializePciDevice (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to initialize the bar of a PCI device
+ It can be called typically when a device is going to be rejected
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 Offset;
+
+ PciIo = &(PciIoDevice->PciIo);
+
+ //
+ // Put all the resource apertures
+ // Resource base is set to all ones so as to indicate its resource
+ // has not been alloacted
+ //
+ for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializePpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ PciIo = &(PciIoDevice->PciIo);
+
+ //
+ // Put all the resource apertures including IO16
+ // Io32, pMem32, pMem64 to quiescent state
+ // Resource base all ones, Resource limit all zeros
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);
+
+ //
+ // don't support use io32 as for now
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);
+
+ //
+ // Force Interrupt line to zero for cards that come up randomly
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeP2C (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ PciIo = &(PciIoDevice->PciIo);
+
+ //
+ // Put all the resource apertures including IO16
+ // Io32, pMem32, pMem64 to quiescent state(
+ // Resource base all ones, Resource limit all zeros
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);
+
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);
+
+ //
+ // Force Interrupt line to zero for cards that come up randomly
+ //
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);
+ return EFI_SUCCESS;
+}
+
+PCI_IO_DEVICE *
+CreatePciIoDevice (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+{
+
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = NULL;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (PCI_IO_DEVICE),
+ (VOID **) &PciIoDevice
+ );
+
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));
+
+ PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;
+ PciIoDevice->Handle = NULL;
+ PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;
+ PciIoDevice->DevicePath = NULL;
+ PciIoDevice->BusNumber = Bus;
+ PciIoDevice->DeviceNumber = Device;
+ PciIoDevice->FunctionNumber = Func;
+ PciIoDevice->Decodes = 0;
+ if (gFullEnumeration) {
+ PciIoDevice->Allocated = FALSE;
+ } else {
+ PciIoDevice->Allocated = TRUE;
+ }
+
+ PciIoDevice->Registered = FALSE;
+ PciIoDevice->Attributes = 0;
+ PciIoDevice->Supports = 0;
+ PciIoDevice->BusOverride = FALSE;
+ PciIoDevice->AllOpRomProcessed = FALSE;
+
+ PciIoDevice->IsPciExp = FALSE;
+
+ CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));
+
+ //
+ // Initialize the PCI I/O instance structure
+ //
+
+ Status = InitializePciIoInstance (PciIoDevice);
+ Status = InitializePciDriverOverrideInstance (PciIoDevice);
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (PciIoDevice);
+ return NULL;
+ }
+
+ //
+ // Initialize the reserved resource list
+ //
+ InitializeListHead (&PciIoDevice->ReservedResourceList);
+
+ //
+ // Initialize the driver list
+ //
+ InitializeListHead (&PciIoDevice->OptionRomDriverList);
+
+ //
+ // Initialize the child list
+ //
+ InitializeListHead (&PciIoDevice->ChildList);
+
+ return PciIoDevice;
+}
+
+EFI_STATUS
+PciEnumeratorLight (
+ IN EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to enumerate entire pci bus system
+ in a given platform
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Controller - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ PCI_IO_DEVICE *RootBridgeDev;
+ UINT16 MinBus;
+ UINT16 MaxBus;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+
+ MinBus = 0;
+ MaxBus = PCI_MAX_BUS;
+ Descriptors = NULL;
+
+ //
+ // If this host bridge has been already enumerated, then return successfully
+ //
+ if (RootBridgeExisted (Controller)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Open pci root bridge io protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {
+
+ //
+ // Create a device node for root bridge device with a NULL host bridge controller handle
+ //
+ RootBridgeDev = CreateRootBridge (Controller);
+
+ if (!RootBridgeDev) {
+ Descriptors++;
+ continue;
+ }
+
+ //
+ // Record the root bridge io protocol
+ //
+ RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;
+
+ Status = PciPciDeviceInfoCollector (
+ RootBridgeDev,
+ (UINT8) MinBus
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Remove those PCI devices which are rejected when full enumeration
+ //
+ RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);
+
+ //
+ // Process option rom light
+ //
+ ProcessOptionRomLight (RootBridgeDev);
+
+ //
+ // Determine attributes for all devices under this root bridge
+ //
+ DetermineDeviceAttribute (RootBridgeDev);
+
+ //
+ // If successfully, insert the node into device pool
+ //
+ InsertRootBridge (RootBridgeDev);
+ } else {
+
+ //
+ // If unsuccessly, destroy the entire node
+ //
+ DestroyRootBridge (RootBridgeDev);
+ }
+
+ Descriptors++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciGetBusRange (
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
+ OUT UINT16 *MinBus,
+ OUT UINT16 *MaxBus,
+ OUT UINT16 *BusRange
+ )
+/*++
+
+Routine Description:
+
+ Get the bus range.
+
+Arguments:
+
+ Descriptors - A pointer to the address space descriptor.
+ MinBus - The min bus.
+ MaxBus - The max bus.
+ BusRange - The bus range.
+
+Returns:
+
+ Status Code.
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+
+ while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
+ if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
+ if (MinBus != NULL) {
+ *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
+ }
+
+ if (MaxBus != NULL) {
+ *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
+ }
+
+ if (BusRange != NULL) {
+ *BusRange = (UINT16) (*Descriptors)->AddrLen;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ (*Descriptors)++;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+StartManagingRootBridge (
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: RootBridgeDev - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE RootBridgeHandle;
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ //
+ // Get the root bridge handle
+ //
+ RootBridgeHandle = RootBridgeDev->Handle;
+ PciRootBridgeIo = NULL;
+
+ //
+ // Get the pci root bridge io protocol
+ //
+ Status = gBS->OpenProtocol (
+ RootBridgeHandle,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ gPciBusDriverBinding.DriverBindingHandle,
+ RootBridgeHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ //
+ // Store the PciRootBridgeIo protocol into root bridge private data
+ //
+ RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;
+
+ return EFI_SUCCESS;
+
+}
+
+BOOLEAN
+IsPciDeviceRejected (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ This routine can be used to check whether a PCI device should be rejected when light enumeration
+
+Arguments:
+
+Returns:
+
+ TRUE This device should be rejected
+ FALSE This device shouldn't be rejected
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ UINT32 TestValue;
+ UINT32 OldValue;
+ UINT32 Mask;
+ UINT8 BarOffset;
+
+ //
+ // PPB should be skip!
+ //
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
+ return FALSE;
+ }
+
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+ //
+ // Only test base registers for P2C
+ //
+ for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {
+
+ Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ TestValue = TestValue & Mask;
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
+ //
+ // The bar isn't programed, so it should be rejected
+ //
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+ }
+
+ for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) {
+ //
+ // Test PCI devices
+ //
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (TestValue & 0x01) {
+
+ //
+ // IO Bar
+ //
+
+ Mask = 0xFFFFFFFC;
+ TestValue = TestValue & Mask;
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
+ return TRUE;
+ }
+
+ } else {
+
+ //
+ // Mem Bar
+ //
+
+ Mask = 0xFFFFFFF0;
+ TestValue = TestValue & Mask;
+
+ if ((TestValue & 0x07) == 0x04) {
+
+ //
+ // Mem64 or PMem64
+ //
+ BarOffset += sizeof (UINT32);
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
+
+ //
+ // Test its high 32-Bit BAR
+ //
+
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);
+ if (TestValue == OldValue) {
+ return TRUE;
+ }
+ }
+
+ } else {
+
+ //
+ // Mem32 or PMem32
+ //
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+ResetAllPpbBusReg (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ StartBusNumber - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ PCI_TYPE00 Pci;
+ UINT8 Device;
+ UINT32 Register;
+ UINT8 Func;
+ UINT64 Address;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+ //
+ // Check to see whether a pci device is present
+ //
+ Status = PciDevicePresent (
+ PciRootBridgeIo,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func
+ );
+
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {
+ Register = 0;
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &Register
+ );
+ //
+ // Reset register 18h, 19h, 1Ah on PCI Bridge
+ //
+ Register &= 0xFF000000;
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &Register
+ );
+ }
+
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h new file mode 100644 index 0000000000..41d6efb102 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h @@ -0,0 +1,598 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciEnumeratorSupport.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H
+#define _EFI_PCI_ENUMERATOR_SUPPORT_H
+
+EFI_STATUS
+PciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciRootBridgeIo - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciPciDeviceInfoCollector (
+ IN PCI_IO_DEVICE *Bridge,
+ UINT8 StartBusNumber
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ StartBusNumber - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciSearchDevice (
+ IN PCI_IO_DEVICE *Bridge,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func,
+ PCI_IO_DEVICE **PciDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+ PciDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+GatherDeviceInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+GatherPpbInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+GatherP2CInfo (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreatePciDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ParentDevicePath - TODO: add argument description
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+BarExisted (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Offset,
+ OUT UINT32 *BarLengthValue,
+ OUT UINT32 *OriginalBarValue
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Offset - TODO: add argument description
+ BarLengthValue - TODO: add argument description
+ OriginalBarValue - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciTestSupportedAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 *Command,
+ IN UINT16 *BridgeControl,
+ IN UINT16 *OldCommand,
+ IN UINT16 *OldBridgeControl
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Command - TODO: add argument description
+ BridgeControl - TODO: add argument description
+ OldCommand - TODO: add argument description
+ OldBridgeControl - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciSetDeviceAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT16 Command,
+ IN UINT16 BridgeControl,
+ IN UINTN Option
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Command - TODO: add argument description
+ BridgeControl - TODO: add argument description
+ Option - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetFastBackToBackSupport (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT8 StatusIndex
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ StatusIndex - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DetermineDeviceAttribute (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UpdatePciInfo (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+SetNewAlign (
+ IN UINT64 *Alignment,
+ IN UINT64 NewAlignment
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Alignment - TODO: add argument description
+ NewAlignment - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+UINTN
+PciParseBar (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Offset,
+ IN UINTN BarIndex
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Offset - TODO: add argument description
+ BarIndex - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InitializePciDevice (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InitializePpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InitializeP2C (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_IO_DEVICE *
+CreatePciIoDevice (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ IN PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciRootBridgeIo - TODO: add argument description
+ Pci - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Func - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciEnumeratorLight (
+ IN EFI_HANDLE Controller
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Controller - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciGetBusRange (
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
+ OUT UINT16 *MinBus,
+ OUT UINT16 *MaxBus,
+ OUT UINT16 *BusRange
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Descriptors - TODO: add argument description
+ MinBus - TODO: add argument description
+ MaxBus - TODO: add argument description
+ BusRange - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+StartManagingRootBridge (
+ IN PCI_IO_DEVICE *RootBridgeDev
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeDev - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsPciDeviceRejected (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c new file mode 100644 index 0000000000..4ebf9a7afc --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c @@ -0,0 +1,462 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciHotPlugSupport.c
+
+Abstract:
+
+
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+#include "PciHotPlugSupport.h"
+
+EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;
+EFI_HPC_LOCATION *gPciRootHpcPool;
+UINTN gPciRootHpcCount;
+ROOT_HPC_DATA *gPciRootHpcData;
+
+VOID
+EFIAPI
+PciHPCInitialized (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Event - add argument and description to function comment
+// TODO: Context - add argument and description to function comment
+{
+ ROOT_HPC_DATA *HpcData;
+
+ HpcData = (ROOT_HPC_DATA *) Context;
+ HpcData->Initialized = TRUE;
+
+}
+
+BOOLEAN
+EfiCompareDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: DevicePath1 - add argument and description to function comment
+// TODO: DevicePath2 - add argument and description to function comment
+{
+ UINTN Size1;
+ UINTN Size2;
+
+ Size1 = GetDevicePathSize (DevicePath1);
+ Size2 = GetDevicePathSize (DevicePath2);
+
+ if (Size1 != Size2) {
+ return FALSE;
+ }
+
+ if (CompareMem (DevicePath1, DevicePath2, Size1)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+EFI_STATUS
+InitializeHotPlugSupport (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_HPC_LOCATION *HpcList;
+ UINTN HpcCount;
+
+ //
+ // Locate the PciHotPlugInit Protocol
+ // If it doesn't exist, that means there is no
+ // hot plug controller supported on the platform
+ // the PCI Bus driver is running on. HotPlug Support
+ // is an optional feature, so absence of the protocol
+ // won't incur the penalty
+ //
+ gPciHotPlugInit = NULL;
+ gPciRootHpcPool = NULL;
+ gPciRootHpcCount = 0;
+ gPciRootHpcData = NULL;
+
+ Status = gBS->LocateProtocol (
+ &gEfiPciHotPlugInitProtocolGuid,
+ NULL,
+ (VOID **) &gPciHotPlugInit
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gPciHotPlugInit->GetRootHpcList (
+ gPciHotPlugInit,
+ &HpcCount,
+ &HpcList
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ gPciRootHpcPool = HpcList;
+ gPciRootHpcCount = HpcCount;
+ gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount);
+ if (gPciRootHpcData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsRootPciHotPlugBus (
+ IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,
+ OUT UINTN *HpIndex
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+ HpIndex - A pointer to the Index.
+
+Returns:
+
+ None
+
+--*/
+// TODO: HpbDevicePath - add argument and description to function comment
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {
+
+ if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) {
+
+ if (HpIndex != NULL) {
+ *HpIndex = Index;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IsRootPciHotPlugController (
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ OUT UINTN *HpIndex
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+ HpIndex - A pointer to the Index.
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {
+
+ if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) {
+
+ if (HpIndex != NULL) {
+ *HpIndex = Index;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+CreateEventForHpc (
+ IN UINTN HpIndex,
+ OUT EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: HpIndex - add argument and description to function comment
+// TODO: Event - add argument and description to function comment
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ PciHPCInitialized,
+ gPciRootHpcData + HpIndex,
+ &((gPciRootHpcData + HpIndex)->Event)
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *Event = (gPciRootHpcData + HpIndex)->Event;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+AllRootHPCInitialized (
+ IN UINTN TimeoutInMilliSeconds
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_TIMEOUT - add return value to function comment
+{
+ UINT32 Delay;
+ UINTN Index;
+
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);
+ do {
+
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {
+
+ if (!gPciRootHpcData[Index].Initialized) {
+ break;
+ }
+ }
+
+ if (Index == gPciRootHpcCount) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Stall for 30 us
+ //
+ gBS->Stall (30);
+
+ Delay--;
+
+ } while (Delay);
+
+ return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+IsSHPC (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+
+ EFI_STATUS Status;
+ UINT8 Offset;
+
+ if (!PciIoDevice) {
+ return EFI_NOT_FOUND;
+ }
+
+ Offset = 0;
+ Status = LocateCapabilityRegBlock (
+ PciIoDevice,
+ EFI_PCI_CAPABILITY_ID_HOTPLUG,
+ &Offset,
+ NULL
+ );
+
+ //
+ // If the PPB has the hot plug controller build-in,
+ // then return TRUE;
+ //
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetResourcePaddingForHpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_HPC_STATE State;
+ UINT64 PciAddress;
+ EFI_HPC_PADDING_ATTRIBUTES Attributes;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+
+ Status = IsPciHotPlugBus (PciIoDevice);
+
+ if (!EFI_ERROR (Status)) {
+ PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);
+ Status = gPciHotPlugInit->GetResourcePadding (
+ gPciHotPlugInit,
+ PciIoDevice->DevicePath,
+ PciAddress,
+ &State,
+ (VOID **) &Descriptors,
+ &Attributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {
+ PciIoDevice->ResourcePaddingDescriptors = Descriptors;
+ PciIoDevice->PaddingAttributes = Attributes;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+IsPciHotPlugBus (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ BOOLEAN Result;
+ EFI_STATUS Status;
+
+ Status = IsSHPC (PciIoDevice);
+
+ //
+ // If the PPB has the hot plug controller build-in,
+ // then return TRUE;
+ //
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Otherwise, see if it is a Root HPC
+ //
+ Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);
+
+ if (Result) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h new file mode 100644 index 0000000000..df49ebaf56 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h @@ -0,0 +1,269 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciHotPlugSupport.h
+
+Abstract:
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H
+#define _EFI_PCI_HOT_PLUG_SUPPORT_H
+
+//
+// stall 1 ms
+//
+#define STALL_1_MILLI_SECOND 1000
+
+//
+// stall 1 second
+//
+#define STALL_1_SECOND 1000000
+
+typedef struct {
+ EFI_EVENT Event;
+ BOOLEAN Initialized;
+ VOID *Padding;
+} ROOT_HPC_DATA;
+
+extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;
+extern EFI_HPC_LOCATION *gPciRootHpcPool;
+extern UINTN gPciRootHpcCount;
+extern ROOT_HPC_DATA *gPciRootHpcData;
+
+VOID
+EFIAPI
+PciHPCInitialized (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Event - TODO: add argument description
+ Context - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+EfiCompareDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ DevicePath1 - TODO: add argument description
+ DevicePath2 - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InitializeHotPlugSupport (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+IsPciHotPlugBus (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsRootPciHotPlugBus (
+ IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,
+ OUT UINTN *HpIndex
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HpbDevicePath - TODO: add argument description
+ HpIndex - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsRootPciHotPlugController (
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ OUT UINTN *HpIndex
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HpcDevicePath - TODO: add argument description
+ HpIndex - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CreateEventForHpc (
+ IN UINTN HpIndex,
+ OUT EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HpIndex - TODO: add argument description
+ Event - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+AllRootHPCInitialized (
+ IN UINTN TimeoutInMilliSeconds
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ TimeoutInMilliSeconds - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+IsSHPC (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourcePaddingForHpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c new file mode 100644 index 0000000000..4f1737f5af --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c @@ -0,0 +1,1964 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciIo.c
+
+Abstract:
+
+ PCI I/O Abstraction Driver
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+
+//
+// Internal use only
+//
+STATIC
+EFI_STATUS
+ReportErrorStatusCode (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_STATUS_CODE_VALUE Code
+ );
+
+//
+// PCI I/O Support Function Prototypes
+//
+//
+//
+// Pci Io Protocol Interface
+//
+static EFI_PCI_IO_PROTOCOL PciIoInterface = {
+ PciIoPollMem,
+ PciIoPollIo,
+ {
+ PciIoMemRead,
+ PciIoMemWrite
+ },
+ {
+ PciIoIoRead,
+ PciIoIoWrite
+ },
+ {
+ PciIoConfigRead,
+ PciIoConfigWrite
+ },
+ PciIoCopyMem,
+ PciIoMap,
+ PciIoUnmap,
+ PciIoAllocateBuffer,
+ PciIoFreeBuffer,
+ PciIoFlush,
+ PciIoGetLocation,
+ PciIoAttributes,
+ PciIoGetBarAttributes,
+ PciIoSetBarAttributes,
+ 0,
+ NULL
+};
+
+STATIC
+EFI_STATUS
+ReportErrorStatusCode (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_STATUS_CODE_VALUE Code
+ )
+/*++
+
+Routine Description:
+
+ report a error Status code of PCI bus driver controller
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Code - add argument and description to function comment
+{
+ return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ Code,
+ PciIoDevice->DevicePath
+ );
+}
+
+EFI_STATUS
+InitializePciIoInstance (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Initializes a PCI I/O Instance
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoVerifyBarAccess (
+ PCI_IO_DEVICE *PciIoDevice,
+ UINT8 BarIndex,
+ PCI_BAR_TYPE Type,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ UINT64 *Offset
+ )
+/*++
+
+Routine Description:
+
+ Verifies access to a PCI Base Address Register (BAR)
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Type - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // BarIndex 0-5 is legal
+ //
+ if (BarIndex >= PCI_MAX_BAR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!CheckBarType (PciIoDevice, BarIndex, Type)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+ //
+ if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+ Count = 1;
+ }
+
+ Width &= 0x03;
+
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoVerifyConfigAccess (
+ PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN UINT64 *Offset
+ )
+/*++
+
+Routine Description:
+
+ Verifies access to a PCI Config Header
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT64 ExtendOffset;
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+ //
+ Width &= 0x03;
+
+ if (PciIoDevice->IsPciExp) {
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ExtendOffset = LShiftU64 (*Offset, 32);
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);
+ *Offset = (*Offset) | ExtendOffset;
+
+ } else {
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoPollMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll PCI Memmory
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Mask - add argument and description to function comment
+// TODO: Value - add argument and description to function comment
+// TODO: Delay - add argument and description to function comment
+// TODO: Result - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Width > EfiPciIoWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->PollMem (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Mask,
+ Value,
+ Delay,
+ Result
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoPollIo (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll PCI IO
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Mask - add argument and description to function comment
+// TODO: Value - add argument and description to function comment
+// TODO: Delay - add argument and description to function comment
+// TODO: Result - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Width > EfiPciIoWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->PollIo (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Mask,
+ Value,
+ Delay,
+ Result
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMemRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI Memory Read Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Read (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMemWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI Memory Write Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Write (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoIoRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI I/O Read Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Io.Read (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoIoWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI I/O Write Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Io.Write (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Offset,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoConfigRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI Configuration Read Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+ UINT64 Address;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ Address = Offset;
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Read (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoConfigWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs a PCI Configuration Write Cycle
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: Buffer - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+ UINT64 Address;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ Address = Offset;
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Write (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoCopyMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ Copy PCI Memory
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Width - add argument and description to function comment
+// TODO: DestBarIndex - add argument and description to function comment
+// TODO: DestOffset - add argument and description to function comment
+// TODO: SrcBarIndex - add argument and description to function comment
+// TODO: SrcOffset - add argument and description to function comment
+// TODO: Count - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width == EfiPciIoWidthFifoUint8 ||
+ Width == EfiPciIoWidthFifoUint16 ||
+ Width == EfiPciIoWidthFifoUint32 ||
+ Width == EfiPciIoWidthFifoUint64 ||
+ Width == EfiPciIoWidthFillUint8 ||
+ Width == EfiPciIoWidthFillUint16 ||
+ Width == EfiPciIoWidthFillUint32 ||
+ Width == EfiPciIoWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->CopyMem (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ DestOffset,
+ SrcOffset,
+ Count
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoMap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+/*++
+
+Routine Description:
+
+ Maps a memory region for DMA
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: HostAddress - add argument and description to function comment
+// TODO: NumberOfBytes - add argument and description to function comment
+// TODO: DeviceAddress - add argument and description to function comment
+// TODO: Mapping - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
+ Operation = Operation + EfiPciOperationBusMasterRead64;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->Map (
+ PciIoDevice->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoUnmap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+/*++
+
+Routine Description:
+
+ Unmaps a memory region for DMA
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Mapping - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ Status = PciIoDevice->PciRootBridgeIo->Unmap (
+ PciIoDevice->PciRootBridgeIo,
+ Mapping
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoAllocateBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Allocates a common buffer for DMA
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Type - add argument and description to function comment
+// TODO: MemoryType - add argument and description to function comment
+// TODO: Pages - add argument and description to function comment
+// TODO: HostAddress - add argument and description to function comment
+// TODO: Attributes - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ if (Attributes &
+ (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
+ Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+ }
+
+ Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (
+ PciIoDevice->PciRootBridgeIo,
+ Type,
+ MemoryType,
+ Pages,
+ HostAddress,
+ Attributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoFreeBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+/*++
+
+Routine Description:
+
+ Frees a common buffer
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Pages - add argument and description to function comment
+// TODO: HostAddress - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (
+ PciIoDevice->PciRootBridgeIo,
+ Pages,
+ HostAddress
+ );
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoFlush (
+ IN EFI_PCI_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ Flushes a DMA buffer
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ Status = PciIoDevice->PciRootBridgeIo->Flush (
+ PciIoDevice->PciRootBridgeIo
+ );
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoGetLocation (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *Segment,
+ OUT UINTN *Bus,
+ OUT UINTN *Device,
+ OUT UINTN *Function
+ )
+/*++
+
+Routine Description:
+
+ Gets a PCI device's current bus number, device number, and function number.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Segment - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Function - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *PciIoDevice;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;
+ *Bus = PciIoDevice->BusNumber;
+ *Device = PciIoDevice->DeviceNumber;
+ *Function = PciIoDevice->FunctionNumber;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+CheckBarType (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ UINT8 BarIndex,
+ PCI_BAR_TYPE BarType
+ )
+/*++
+
+Routine Description:
+
+ Sets a PCI controllers attributes on a resource range
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: BarType - add argument and description to function comment
+{
+ switch (BarType) {
+
+ case PciBarTypeMem:
+
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {
+ return FALSE;
+ }
+
+ return TRUE;
+
+ case PciBarTypeIo:
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){
+ return FALSE;
+ }
+
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+ModifyRootBridgeAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT64 Attributes,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
+ )
+/*++
+
+Routine Description:
+
+ Set new attributes to a Root Bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Attributes - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT64 PciRootBridgeSupports;
+ UINT64 PciRootBridgeAttributes;
+ UINT64 NewPciRootBridgeAttributes;
+ EFI_STATUS Status;
+
+ //
+ // Get the current attributes of this PCI device's PCI Root Bridge
+ //
+ Status = PciIoDevice->PciRootBridgeIo->GetAttributes (
+ PciIoDevice->PciRootBridgeIo,
+ &PciRootBridgeSupports,
+ &PciRootBridgeAttributes
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Record the new attribute of the Root Bridge
+ //
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;
+ } else {
+ NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);
+ }
+
+ //
+ // Call the PCI Root Bridge to attempt to modify the attributes
+ //
+ if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {
+
+ Status = PciIoDevice->PciRootBridgeIo->SetAttributes (
+ PciIoDevice->PciRootBridgeIo,
+ NewPciRootBridgeAttributes,
+ NULL,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // The PCI Root Bridge could not modify the attributes, so return the error.
+ //
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Also update the attributes for this Root Bridge structure
+ //
+ PciIoDevice->Attributes = NewPciRootBridgeAttributes;
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+SupportPaletteSnoopAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
+ )
+/*++
+
+Routine Description:
+
+ Check whether this device can be enable/disable to snoop
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Temp;
+ UINT16 VGACommand;
+
+ //
+ // Snoop attribute can be only modified by GFX
+ //
+ if (!IS_PCI_GFX (&PciIoDevice->Pci)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the boot VGA on the same segement
+ //
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
+
+ if (!Temp) {
+ //
+ // If there is no VGA device on the segement, set
+ // this graphics card to decode the palette range
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check these two agents are on the same path
+ //
+ if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {
+ //
+ // they are not on the same path, so snoop can be enabled or disabled
+ //
+ return EFI_SUCCESS;
+ }
+ //
+ // Check if they are on the same bus
+ //
+ if (Temp->Parent == PciIoDevice->Parent) {
+
+ PciReadCommandRegister (Temp, &VGACommand);
+
+ //
+ // If they are on the same bus, either one can
+ // be set to snoop, the other set to decode
+ //
+ if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
+ //
+ // VGA has set to snoop, so GFX can be only set to disable snoop
+ //
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ //
+ // VGA has disabled to snoop, so GFX can be only enabled
+ //
+ if (Operation == EfiPciIoAttributeOperationDisable) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If they are on the same path but on the different bus
+ // The first agent is set to snoop, the second one set to
+ // decode
+ //
+
+ if (Temp->BusNumber > PciIoDevice->BusNumber) {
+ //
+ // GFX should be set to decode
+ //
+ if (Operation == EfiPciIoAttributeOperationDisable) {
+ PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
+ Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ } else {
+ //
+ // GFX should be set to snoop
+ //
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
+ Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoAttributes (
+ IN EFI_PCI_IO_PROTOCOL * This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: Attributes - add argument and description to function comment
+// TODO: Result - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+
+ PCI_IO_DEVICE *PciIoDevice;
+ PCI_IO_DEVICE *UpStreamBridge;
+ PCI_IO_DEVICE *Temp;
+
+ UINT64 Supports;
+ UINT64 UpStreamAttributes;
+ UINT16 BridgeControl;
+ UINT16 Command;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ switch (Operation) {
+ case EfiPciIoAttributeOperationGet:
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Result = PciIoDevice->Attributes;
+ return EFI_SUCCESS;
+
+ case EfiPciIoAttributeOperationSupported:
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Result = PciIoDevice->Supports;
+ return EFI_SUCCESS;
+
+ case EfiPciIoAttributeOperationSet:
+ Status = PciIoDevice->PciIo.Attributes (
+ &(PciIoDevice->PciIo),
+ EfiPciIoAttributeOperationEnable,
+ Attributes,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIoDevice->PciIo.Attributes (
+ &(PciIoDevice->PciIo),
+ EfiPciIoAttributeOperationDisable,
+ (~Attributes) & (PciIoDevice->Supports),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+
+ case EfiPciIoAttributeOperationEnable:
+ case EfiPciIoAttributeOperationDisable:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Just a trick for ENABLE attribute
+ //
+ if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {
+ Attributes &= (PciIoDevice->Supports);
+
+ //
+ // Raise the EFI_P_PC_ENABLE Status code
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,
+ PciIoDevice->DevicePath
+ );
+ }
+
+ //
+ // If no attributes can be supported, then return.
+ // Otherwise, set the attributes that it can support.
+ //
+ Supports = (PciIoDevice->Supports) & Attributes;
+ if (Supports != Attributes) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // For Root Bridge, just call RootBridgeIo to set attributes;
+ //
+ if (!PciIoDevice->Parent) {
+ Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);
+ return Status;
+ }
+
+ Command = 0;
+ BridgeControl = 0;
+
+ //
+ // For PPB & P2C, set relevant attribute bits
+ //
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {
+ BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;
+ }
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {
+ BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;
+ }
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {
+ Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+ }
+
+ } else {
+ //
+ // Do with the attributes on VGA
+ //
+ if ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ||
+ (IS_PCI_VGA(&PciIoDevice->Pci) &&
+ ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) ||
+ (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)))) {
+ //
+ // Check if a VGA has been enabled before enabling a new one
+ //
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ //
+ // Check if there have been an active VGA device on the same segment
+ //
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
+ if (Temp && Temp != PciIoDevice) {
+ //
+ // An active VGA has been detected, so can not enable another
+ //
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ //
+ // Do with the attributes on GFX
+ //
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {
+
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ //
+ // Check if snoop can be enabled in current configuration
+ //
+ Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);
+
+ if (EFI_ERROR (Status)) {
+
+ //
+ // Enable operation is forbidden, so mask the bit in attributes
+ // so as to keep consistent with the actual Status
+ //
+ // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);
+ //
+ //
+ //
+ return EFI_UNSUPPORTED;
+
+ }
+ }
+
+ //
+ // It can be supported, so get ready to set the bit
+ //
+ Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
+ }
+ }
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {
+ Command |= EFI_PCI_COMMAND_IO_SPACE;
+ }
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {
+ Command |= EFI_PCI_COMMAND_MEMORY_SPACE;
+ }
+
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {
+ Command |= EFI_PCI_COMMAND_BUS_MASTER;
+ }
+ //
+ // The upstream bridge should be also set to revelant attribute
+ // expect for IO, Mem and BusMaster
+ //
+ UpStreamAttributes = Attributes &
+ (~(EFI_PCI_IO_ATTRIBUTE_IO |
+ EFI_PCI_IO_ATTRIBUTE_MEMORY |
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
+ )
+ );
+ UpStreamBridge = PciIoDevice->Parent;
+
+ if (Operation == EfiPciIoAttributeOperationEnable) {
+ //
+ // Enable relevant attributes to command register and bridge control register
+ //
+ Status = PciEnableCommandRegister (PciIoDevice, Command);
+ if (BridgeControl) {
+ Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);
+ }
+
+ PciIoDevice->Attributes |= Attributes;
+
+ //
+ // Enable attributes of the upstream bridge
+ //
+ Status = UpStreamBridge->PciIo.Attributes (
+ &(UpStreamBridge->PciIo),
+ EfiPciIoAttributeOperationEnable,
+ UpStreamAttributes,
+ NULL
+ );
+ } else {
+
+ //
+ // Disable relevant attributes to command register and bridge control register
+ //
+ Status = PciDisableCommandRegister (PciIoDevice, Command);
+ if (BridgeControl) {
+ Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);
+ }
+
+ PciIoDevice->Attributes &= (~Attributes);
+ Status = EFI_SUCCESS;
+
+ }
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoGetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL * This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Supports - add argument and description to function comment
+// TODO: Resources - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ UINT8 *Configuration;
+ UINT8 NumConfig;
+ PCI_IO_DEVICE *PciIoDevice;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;
+
+ NumConfig = 0;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ if (Supports == NULL && Resources == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BarIndex >= PCI_MAX_BAR) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // This driver does not support modifications to the WRITE_COMBINE or
+ // CACHED attributes for BAR ranges.
+ //
+ if (Supports != NULL) {
+ *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
+ }
+
+ if (Resources != NULL) {
+
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {
+ NumConfig = 1;
+ }
+
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (Configuration == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (
+ Configuration,
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
+ );
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+
+ if (NumConfig == 1) {
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+
+ Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;
+ Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;
+ Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;
+
+ switch (PciIoDevice->PciBar[BarIndex].BarType) {
+ case PciBarTypeIo16:
+ case PciBarTypeIo32:
+ //
+ // Io
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+ break;
+
+ case PciBarTypeMem32:
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // 32 bit
+ //
+ Ptr->AddrSpaceGranularity = 32;
+ break;
+
+ case PciBarTypePMem32:
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // prefechable
+ //
+ Ptr->SpecificFlag = 0x6;
+ //
+ // 32 bit
+ //
+ Ptr->AddrSpaceGranularity = 32;
+ break;
+
+ case PciBarTypeMem64:
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // 64 bit
+ //
+ Ptr->AddrSpaceGranularity = 64;
+ break;
+
+ case PciBarTypePMem64:
+ //
+ // Mem
+ //
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ //
+ // prefechable
+ //
+ Ptr->SpecificFlag = 0x6;
+ //
+ // 64 bit
+ //
+ Ptr->AddrSpaceGranularity = 64;
+ break;
+
+ default:
+ break;
+ }
+
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
+ }
+
+ //
+ // put the checksum
+ //
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
+ PtrEnd->Checksum = 0;
+
+ *Resources = Configuration;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciIoSetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Attributes - add argument and description to function comment
+// TODO: BarIndex - add argument and description to function comment
+// TODO: Offset - add argument and description to function comment
+// TODO: Length - add argument and description to function comment
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+ UINT64 NonRelativeOffset;
+ UINT64 Supports;
+
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+
+ //
+ // Make sure Offset and Length are not NULL
+ //
+ if (Offset == NULL || Length == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.
+ // If Attributes is not 0, then return EFI_UNSUPPORTED.
+ //
+ Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
+
+ if (Attributes != (Attributes & Supports)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and
+ // Length are valid for this PCI device.
+ //
+ NonRelativeOffset = *Offset;
+ Status = PciIoVerifyBarAccess (
+ PciIoDevice,
+ BarIndex,
+ PciBarTypeMem,
+ EfiPciIoWidthUint8,
+ (UINT32) *Length,
+ &NonRelativeOffset
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpStreamBridgesAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: Operation - add argument and description to function comment
+// TODO: Attributes - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Parent;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ Parent = PciIoDevice->Parent;
+
+ while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {
+
+ //
+ // Get the PciIo Protocol
+ //
+ PciIo = &Parent->PciIo;
+
+ PciIo->Attributes (PciIo, Operation, Attributes, NULL);
+
+ Parent = Parent->Parent;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+PciDevicesOnTheSamePath (
+ IN PCI_IO_DEVICE *PciDevice1,
+ IN PCI_IO_DEVICE *PciDevice2
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDevice1 - add argument and description to function comment
+// TODO: PciDevice2 - add argument and description to function comment
+{
+
+ if (PciDevice1->Parent == PciDevice2->Parent) {
+ return TRUE;
+ }
+
+ if (PciDevice1->BusNumber > PciDevice2->BusNumber) {
+ return PciDeviceExisted (PciDevice1->Parent, PciDevice2);
+ }
+
+ return PciDeviceExisted (PciDevice2->Parent, PciDevice1);
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h new file mode 100644 index 0000000000..5733f592e3 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h @@ -0,0 +1,773 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciIo.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_IO_PROTOCOL_H
+#define _EFI_PCI_IO_PROTOCOL_H
+
+EFI_STATUS
+InitializePciIoInstance (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciIoVerifyBarAccess (
+ PCI_IO_DEVICE *PciIoDevice,
+ UINT8 BarIndex,
+ PCI_BAR_TYPE Type,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ UINT64 *Offset
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Type - TODO: add argument description
+ Width - TODO: add argument description
+ Count - TODO: add argument description
+ Offset - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciIoVerifyConfigAccess (
+ PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN UINT64 *Offset
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Width - TODO: add argument description
+ Count - TODO: add argument description
+ Offset - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoPollMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Mask - TODO: add argument description
+ Value - TODO: add argument description
+ Delay - TODO: add argument description
+ Result - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoPollIo (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Mask - TODO: add argument description
+ Value - TODO: add argument description
+ Delay - TODO: add argument description
+ Result - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoMemRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoMemWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoIoRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoIoWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoConfigRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoConfigWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ Offset - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoCopyMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Width - TODO: add argument description
+ DestBarIndex - TODO: add argument description
+ DestOffset - TODO: add argument description
+ SrcBarIndex - TODO: add argument description
+ SrcOffset - TODO: add argument description
+ Count - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoMap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Operation - TODO: add argument description
+ HostAddress - TODO: add argument description
+ NumberOfBytes - TODO: add argument description
+ DeviceAddress - TODO: add argument description
+ Mapping - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoUnmap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Mapping - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoAllocateBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Type - TODO: add argument description
+ MemoryType - TODO: add argument description
+ Pages - TODO: add argument description
+ HostAddress - TODO: add argument description
+ Attributes - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoFreeBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Pages - TODO: add argument description
+ HostAddress - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoFlush (
+ IN EFI_PCI_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoGetLocation (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *Segment,
+ OUT UINTN *Bus,
+ OUT UINTN *Device,
+ OUT UINTN *Function
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Segment - TODO: add argument description
+ Bus - TODO: add argument description
+ Device - TODO: add argument description
+ Function - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+CheckBarType (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ UINT8 BarIndex,
+ PCI_BAR_TYPE BarType
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ BarIndex - TODO: add argument description
+ BarType - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ModifyRootBridgeAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINT64 Attributes,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Attributes - TODO: add argument description
+ Operation - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+SupportPaletteSnoopAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Operation - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoAttributes (
+ IN EFI_PCI_IO_PROTOCOL * This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Operation - TODO: add argument description
+ Attributes - TODO: add argument description
+ Result - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoGetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL * This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Supports - TODO: add argument description
+ Resources - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PciIoSetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Attributes - TODO: add argument description
+ BarIndex - TODO: add argument description
+ Offset - TODO: add argument description
+ Length - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+UpStreamBridgesAttributes (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+ Operation - TODO: add argument description
+ Attributes - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+PciDevicesOnTheSamePath (
+ IN PCI_IO_DEVICE *PciDevice1,
+ IN PCI_IO_DEVICE *PciDevice2
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice1 - TODO: add argument description
+ PciDevice2 - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c new file mode 100644 index 0000000000..11a0c29210 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c @@ -0,0 +1,1398 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciLib.c
+
+Abstract:
+
+ PCI Bus Driver Lib file
+ It abstracts some functions that can be different
+ between light PCI bus driver and full PCI bus driver
+
+Revision History
+
+--*/
+
+#include "pcibus.h"
+
+EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {
+ PciHotPlugRequestNotify
+};
+
+
+VOID
+InstallHotPlugRequestProtocol (
+ IN EFI_STATUS *Status
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+ Status - A pointer to the status.
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_HANDLE Handle;
+
+ Handle = NULL;
+ *Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiPciHotPlugRequestProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gPciHotPlugRequest
+ );
+}
+
+VOID
+InstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {
+
+ Status = gBS->InstallProtocolInterface (
+ &PciIoDevice->Handle,
+ &gEfiPciHotplugDeviceGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ }
+}
+
+VOID
+UninstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol (
+ PciIoDevice->Handle,
+ &gEfiPciHotplugDeviceGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // This may triger CardBus driver to stop for
+ // Pccard devices opened the GUID via BY_DRIVER
+ //
+ Status = gBS->UninstallProtocolInterface (
+ PciIoDevice->Handle,
+ &gEfiPciHotplugDeviceGuid,
+ NULL
+ );
+ }
+}
+
+VOID
+GetBackPcCardBar (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT32 Address;
+
+ //
+ // Read PciBar information from the bar register
+ //
+ if (!gFullEnumeration) {
+
+ Address = 0;
+ PciIoDevice->PciIo.Pci.Read (
+ &(PciIoDevice->PciIo),
+ EfiPciIoWidthUint32,
+ 0x1c,
+ 1,
+ &Address
+ );
+
+ (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address);
+ (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000;
+ (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32;
+
+ Address = 0;
+ PciIoDevice->PciIo.Pci.Read (
+ &(PciIoDevice->PciIo),
+ EfiPciIoWidthUint32,
+ 0x20,
+ 1,
+ &Address
+ );
+ (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address);
+ (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000;
+ (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32;
+
+ Address = 0;
+ PciIoDevice->PciIo.Pci.Read (
+ &(PciIoDevice->PciIo),
+ EfiPciIoWidthUint32,
+ 0x2c,
+ 1,
+ &Address
+ );
+ (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address);
+ (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100;
+ (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16;
+
+ Address = 0;
+ PciIoDevice->PciIo.Pci.Read (
+ &(PciIoDevice->PciIo),
+ EfiPciIoWidthUint32,
+ 0x34,
+ 1,
+ &Address
+ );
+ (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address);
+ (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100;
+ (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16;
+
+ }
+
+ if (gPciHotPlugInit != NULL) {
+ GetResourcePaddingForHpb (PciIoDevice);
+ }
+}
+
+EFI_STATUS
+RemoveRejectedPciDevices (
+ EFI_HANDLE RootBridgeHandle,
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+ RootBridgeHandle - An efi handle.
+ Bridge - An pointer to the PCI_IO_DEVICE.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Temp;
+ LIST_ENTRY *CurrentLink;
+ LIST_ENTRY *LastLink;
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {
+ //
+ // Remove rejected devices recusively
+ //
+ RemoveRejectedPciDevices (RootBridgeHandle, Temp);
+ } else {
+ //
+ // Skip rejection for all PPBs, while detect rejection for others
+ //
+ if (IsPciDeviceRejected (Temp)) {
+
+ //
+ // For P2C, remove all devices on it
+ //
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);
+ }
+
+ //
+ // Finally remove itself
+ //
+
+ LastLink = CurrentLink->BackLink;
+ RemoveEntryList (CurrentLink);
+ FreePciDevice (Temp);
+
+ CurrentLink = LastLink;
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHostBridgeResourceAllocator (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ Host brige resource allocator.
+
+Arguments:
+
+ PciResAlloc - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.
+
+Returns:
+
+ EFI Status.
+
+--*/
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_HANDLE RootBridgeHandle;
+ VOID *AcpiConfig;
+ EFI_STATUS Status;
+ UINT64 IoBase;
+ UINT64 Mem32Base;
+ UINT64 PMem32Base;
+ UINT64 Mem64Base;
+ UINT64 PMem64Base;
+ UINT64 IoResStatus;
+ UINT64 Mem32ResStatus;
+ UINT64 PMem32ResStatus;
+ UINT64 Mem64ResStatus;
+ UINT64 PMem64ResStatus;
+ UINT64 MaxOptionRomSize;
+ PCI_RESOURCE_NODE *IoBridge;
+ PCI_RESOURCE_NODE *Mem32Bridge;
+ PCI_RESOURCE_NODE *PMem32Bridge;
+ PCI_RESOURCE_NODE *Mem64Bridge;
+ PCI_RESOURCE_NODE *PMem64Bridge;
+ PCI_RESOURCE_NODE IoPool;
+ PCI_RESOURCE_NODE Mem32Pool;
+ PCI_RESOURCE_NODE PMem32Pool;
+ PCI_RESOURCE_NODE Mem64Pool;
+ PCI_RESOURCE_NODE PMem64Pool;
+ BOOLEAN ReAllocate;
+ REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA HandleExtendedData;
+ REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;
+
+ //
+ // Reallocate flag
+ //
+ ReAllocate = FALSE;
+
+ //
+ // It will try several times if the resource allocation fails
+ //
+ while (TRUE) {
+
+ //
+ // Initialize resource pool
+ //
+ InitializeResourcePool (&IoPool, PciBarTypeIo16);
+ InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);
+ InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);
+ InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);
+ InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);
+
+ RootBridgeDev = NULL;
+ RootBridgeHandle = 0;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Create the entire system resource map from the information collected by
+ // enumerator. Several resource tree was created
+ //
+
+ IoBridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFF,
+ 0,
+ PciBarTypeIo16,
+ PciResUsageTypical
+ );
+
+ Mem32Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem32,
+ PciResUsageTypical
+ );
+
+ PMem32Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem32,
+ PciResUsageTypical
+ );
+
+ Mem64Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypeMem64,
+ PciResUsageTypical
+ );
+
+ PMem64Bridge = CreateResourceNode (
+ RootBridgeDev,
+ 0,
+ 0xFFFFF,
+ 0,
+ PciBarTypePMem64,
+ PciResUsageTypical
+ );
+
+ //
+ // Create resourcemap by going through all the devices subject to this root bridge
+ //
+ Status = CreateResourceMap (
+ RootBridgeDev,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge
+ );
+
+ //
+ // Get the max ROM size that the root bridge can process
+ //
+ RootBridgeDev->RomSize = Mem32Bridge->Length;
+
+ //
+ // Skip to enlarge the resource request during realloction
+ //
+ if (!ReAllocate) {
+ //
+ // Get Max Option Rom size for current root bridge
+ //
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);
+
+ //
+ // Enlarger the mem32 resource to accomdate the option rom
+ // if the mem32 resource is not enough to hold the rom
+ //
+ if (MaxOptionRomSize > Mem32Bridge->Length) {
+
+ Mem32Bridge->Length = MaxOptionRomSize;
+ RootBridgeDev->RomSize = MaxOptionRomSize;
+
+ //
+ // Alignment should be adjusted as well
+ //
+ if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {
+ Mem32Bridge->Alignment = MaxOptionRomSize - 1;
+ }
+ }
+ }
+
+ //
+ // Based on the all the resource tree, contruct ACPI resource node to
+ // submit the resource aperture to pci host bridge protocol
+ //
+ Status = ConstructAcpiResourceRequestor (
+ RootBridgeDev,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge,
+ &AcpiConfig
+ );
+
+ //
+ // Insert these resource nodes into the database
+ //
+ InsertResourceNode (&IoPool, IoBridge);
+ InsertResourceNode (&Mem32Pool, Mem32Bridge);
+ InsertResourceNode (&PMem32Pool, PMem32Bridge);
+ InsertResourceNode (&Mem64Pool, Mem64Bridge);
+ InsertResourceNode (&PMem64Pool, PMem64Bridge);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Submit the resource requirement
+ //
+ Status = PciResAlloc->SubmitResources (
+ PciResAlloc,
+ RootBridgeDev->Handle,
+ AcpiConfig
+ );
+ }
+
+ //
+ // Free acpi resource node
+ //
+ if (AcpiConfig != NULL) {
+ gBS->FreePool (AcpiConfig);
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Destroy all the resource tree
+ //
+ DestroyResourceTree (&IoPool);
+ DestroyResourceTree (&Mem32Pool);
+ DestroyResourceTree (&PMem32Pool);
+ DestroyResourceTree (&Mem64Pool);
+ DestroyResourceTree (&PMem64Pool);
+ return Status;
+ }
+ }
+
+ //
+ // Notify pci bus driver starts to program the resource
+ //
+
+ Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Allocation succeed, then continue the following
+ //
+ break;
+ }
+
+ //
+ // If the resource allocation is unsuccessful, free resources on bridge
+ //
+
+ RootBridgeDev = NULL;
+ RootBridgeHandle = 0;
+
+ IoResStatus = EFI_RESOURCE_SATISFIED;
+ Mem32ResStatus = EFI_RESOURCE_SATISFIED;
+ PMem32ResStatus = EFI_RESOURCE_SATISFIED;
+ Mem64ResStatus = EFI_RESOURCE_SATISFIED;
+ PMem64ResStatus = EFI_RESOURCE_SATISFIED;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get host bridge handle for status report
+ //
+ HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;
+
+ //
+ // Get acpi resource node for all the resource types
+ //
+ AcpiConfig = NULL;
+
+ Status = PciResAlloc->GetProposedResources (
+ PciResAlloc,
+ RootBridgeDev->Handle,
+ &AcpiConfig
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (AcpiConfig != NULL) {
+ //
+ // Adjust resource allocation policy for each RB
+ //
+ GetResourceAllocationStatus (
+ AcpiConfig,
+ &IoResStatus,
+ &Mem32ResStatus,
+ &PMem32ResStatus,
+ &Mem64ResStatus,
+ &PMem64ResStatus
+ );
+ gBS->FreePool (AcpiConfig);
+ }
+ }
+ //
+ // End while
+ //
+
+ //
+ // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
+ //
+ //
+ // It is very difficult to follow the spec here
+ // Device path , Bar index can not be get here
+ //
+ ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));
+
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
+ (VOID *) &AllocFailExtendedData,
+ sizeof (AllocFailExtendedData)
+ );
+
+ Status = PciHostBridgeAdjustAllocation (
+ &IoPool,
+ &Mem32Pool,
+ &PMem32Pool,
+ &Mem64Pool,
+ &PMem64Pool,
+ IoResStatus,
+ Mem32ResStatus,
+ PMem32ResStatus,
+ Mem64ResStatus,
+ PMem64ResStatus
+ );
+
+ //
+ // Destroy all the resource tree
+ //
+ DestroyResourceTree (&IoPool);
+ DestroyResourceTree (&Mem32Pool);
+ DestroyResourceTree (&PMem32Pool);
+ DestroyResourceTree (&Mem64Pool);
+ DestroyResourceTree (&PMem64Pool);
+
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ReAllocate = TRUE;
+
+ }
+ //
+ // End main while
+ //
+
+ //
+ // Raise the EFI_IOB_PCI_RES_ALLOC status code
+ //
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,
+ (VOID *) &HandleExtendedData,
+ sizeof (HandleExtendedData)
+ );
+
+ //
+ // Notify pci bus driver starts to program the resource
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);
+
+ RootBridgeDev = NULL;
+
+ RootBridgeHandle = 0;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get acpi resource node for all the resource types
+ //
+ AcpiConfig = NULL;
+ Status = PciResAlloc->GetProposedResources (
+ PciResAlloc,
+ RootBridgeDev->Handle,
+ &AcpiConfig
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the resource base by interpreting acpi resource node
+ //
+ //
+ GetResourceBase (
+ AcpiConfig,
+ &IoBase,
+ &Mem32Base,
+ &PMem32Base,
+ &Mem64Base,
+ &PMem64Base
+ );
+
+ //
+ // Process option rom for this root bridge
+ //
+ Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);
+
+ //
+ // Create the entire system resource map from the information collected by
+ // enumerator. Several resource tree was created
+ //
+ Status = GetResourceMap (
+ RootBridgeDev,
+ &IoBridge,
+ &Mem32Bridge,
+ &PMem32Bridge,
+ &Mem64Bridge,
+ &PMem64Bridge,
+ &IoPool,
+ &Mem32Pool,
+ &PMem32Pool,
+ &Mem64Pool,
+ &PMem64Pool
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Program IO resources
+ //
+ ProgramResource (
+ IoBase,
+ IoBridge
+ );
+
+ //
+ // Program Mem32 resources
+ //
+ ProgramResource (
+ Mem32Base,
+ Mem32Bridge
+ );
+
+ //
+ // Program PMem32 resources
+ //
+ ProgramResource (
+ PMem32Base,
+ PMem32Bridge
+ );
+
+ //
+ // Program Mem64 resources
+ //
+ ProgramResource (
+ Mem64Base,
+ Mem64Bridge
+ );
+
+ //
+ // Program PMem64 resources
+ //
+ ProgramResource (
+ PMem64Base,
+ PMem64Bridge
+ );
+
+ if (AcpiConfig != NULL) {
+ gBS->FreePool (AcpiConfig);
+ }
+ }
+
+ //
+ // Destroy all the resource tree
+ //
+ DestroyResourceTree (&IoPool);
+ DestroyResourceTree (&Mem32Pool);
+ DestroyResourceTree (&PMem32Pool);
+ DestroyResourceTree (&Mem64Pool);
+ DestroyResourceTree (&PMem64Pool);
+
+ //
+ // Notify the resource allocation phase is to end
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciScanBus (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to assign bus number to the given PCI bus system
+
+Arguments:
+
+ Bridge - A pointer to the PCI_IO_DEVICE structure.
+ StartBusNumber - The start bus number.
+ SubBusNumber - A pointer to the sub bus number.
+ PaddedBusRange - A pointer to the padded bus range.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ PCI_TYPE00 Pci;
+ UINT8 Device;
+ UINT8 Func;
+ UINT64 Address;
+ UINTN SecondBus;
+ UINT16 Register;
+ UINTN HpIndex;
+ PCI_IO_DEVICE *PciDevice;
+ EFI_EVENT Event;
+ EFI_HPC_STATE State;
+ UINT64 PciAddress;
+ EFI_HPC_PADDING_ATTRIBUTES Attributes;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+ UINT16 BusRange;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ BOOLEAN BusPadding;
+
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;
+ SecondBus = 0;
+ Register = 0;
+ State = 0;
+ Attributes = 0;
+ BusRange = 0;
+
+ ResetAllPpbBusReg (Bridge, StartBusNumber);
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+
+ //
+ // Check to see whether a pci device is present
+ //
+ Status = PciDevicePresent (
+ PciRootBridgeIo,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Func == 0) {
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+
+ continue;
+ }
+
+ //
+ // Get the PCI device information
+ //
+ Status = PciSearchDevice (
+ Bridge,
+ &Pci,
+ StartBusNumber,
+ Device,
+ Func,
+ &PciDevice
+ );
+
+ ASSERT (!EFI_ERROR (Status));
+
+ PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);
+
+ if (!IS_PCI_BRIDGE (&Pci)) {
+ //
+ // PCI bridges will be called later
+ // Here just need for PCI device or PCI to cardbus controller
+ // EfiPciBeforeChildBusEnumeration for PCI Device Node
+ //
+ PreprocessController (
+ PciDevice,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ EfiPciBeforeChildBusEnumeration
+ );
+ }
+
+ //
+ // For Pci Hotplug controller devcie only
+ //
+ if (gPciHotPlugInit != NULL) {
+ //
+ // Check if it is a Hotplug PCI controller
+ //
+ if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {
+
+ if (!gPciRootHpcData[HpIndex].Initialized) {
+
+ Status = CreateEventForHpc (HpIndex, &Event);
+
+ ASSERT (!EFI_ERROR (Status));
+
+ Status = gPciHotPlugInit->InitializeRootHpc (
+ gPciHotPlugInit,
+ gPciRootHpcPool[HpIndex].HpcDevicePath,
+ PciAddress,
+ Event,
+ &State
+ );
+
+ PreprocessController (
+ PciDevice,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ EfiPciBeforeChildBusEnumeration
+ );
+ continue;
+ }
+ }
+ }
+
+ if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {
+ //
+ // For PPB
+ // Get the bridge information
+ //
+ BusPadding = FALSE;
+ if (gPciHotPlugInit != NULL) {
+
+ if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {
+
+ //
+ // If it is initialized, get the padded bus range
+ //
+ Status = gPciHotPlugInit->GetResourcePadding (
+ gPciHotPlugInit,
+ gPciRootHpcPool[HpIndex].HpbDevicePath,
+ PciAddress,
+ &State,
+ (VOID **) &Descriptors,
+ &Attributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BusRange = 0;
+ Status = PciGetBusRange (
+ &Descriptors,
+ NULL,
+ NULL,
+ &BusRange
+ );
+
+ gBS->FreePool (Descriptors);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BusPadding = TRUE;
+ }
+ }
+
+ (*SubBusNumber)++;
+ SecondBus = *SubBusNumber;
+
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint16,
+ Address,
+ 1,
+ &Register
+ );
+
+
+ //
+ // If it is PPB, resursively search down this bridge
+ //
+ if (IS_PCI_BRIDGE (&Pci)) {
+
+ //
+ // Initialize SubBusNumber to Maximum bus number
+ //
+ Register = 0xFF;
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ &Register
+ );
+
+ //
+ // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige
+ //
+ PreprocessController (
+ PciDevice,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ EfiPciBeforeChildBusEnumeration
+ );
+
+ Status = PciScanBus (
+ PciDevice,
+ (UINT8) (SecondBus),
+ SubBusNumber,
+ PaddedBusRange
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if (BusPadding) {
+ //
+ // Ensure the device is enabled and initialized
+ //
+ if ((Attributes == EfiPaddingPciRootBridge) &&
+ (State & EFI_HPC_STATE_ENABLED) &&
+ (State & EFI_HPC_STATE_INITIALIZED) ) {
+ *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);
+ } else {
+ *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);
+ }
+ }
+
+ //
+ // Set the current maximum bus number under the PPB
+ //
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint8,
+ Address,
+ 1,
+ SubBusNumber
+ );
+ }
+
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRootBridgeP2CProcess (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ Process Option Rom on this host bridge
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_IO_DEVICE *Temp;
+ EFI_HPC_STATE State;
+ UINT64 PciAddress;
+ EFI_STATUS Status;
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {
+
+ if (gPciHotPlugInit && Temp->Allocated) {
+
+ //
+ // Raise the EFI_IOB_PCI_HPC_INIT status code
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,
+ Temp->DevicePath
+ );
+
+ PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);
+ Status = gPciHotPlugInit->InitializeRootHpc (
+ gPciHotPlugInit,
+ Temp->DevicePath,
+ PciAddress,
+ NULL,
+ &State
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = PciBridgeEnumerator (Temp);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+
+ }
+ }
+
+ if (!IsListEmpty (&Temp->ChildList)) {
+ Status = PciRootBridgeP2CProcess (Temp);
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHostBridgeP2CProcess (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciResAlloc - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE RootBridgeHandle;
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_STATUS Status;
+
+ RootBridgeHandle = NULL;
+
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // Get RootBridg Device by handle
+ //
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = PciRootBridgeP2CProcess (RootBridgeDev);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHostBridgeEnumerator (
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ This function is used to enumerate the entire host bridge
+ in a given platform
+
+Arguments:
+
+ PciResAlloc - A pointer to the resource allocate protocol.
+
+Returns:
+
+ None
+
+--*/
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_HANDLE RootBridgeHandle;
+ PCI_IO_DEVICE *RootBridgeDev;
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ UINT16 MinBus;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+
+ InitializeHotPlugSupport ();
+
+ //
+ // Notify the bus allocation phase is about to start
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
+
+ RootBridgeHandle = NULL;
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
+
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Enumerate all the buses under this root bridge
+ //
+
+ Status = PciRootBridgeEnumerator (
+ PciResAlloc,
+ RootBridgeDev
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DestroyRootBridge (RootBridgeDev);
+
+ //
+ // Error proccess here
+ //
+ }
+
+ //
+ // Notify the bus allocation phase is finished for the first time
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
+
+
+ if (gPciHotPlugInit != NULL) {
+ //
+ // Wait for all HPC initialized
+ //
+ Status = AllRootHPCInitialized (STALL_1_SECOND * 15);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Notify the bus allocation phase is about to start for the 2nd time
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
+
+ RootBridgeHandle = NULL;
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
+
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Enumerate all the buses under this root bridge
+ //
+
+ Status = PciRootBridgeEnumerator (
+ PciResAlloc,
+ RootBridgeDev
+ );
+
+ DestroyRootBridge (RootBridgeDev);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Notify the bus allocation phase is to end
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
+ }
+
+ //
+ // Notify the resource allocation phase is to start
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);
+
+ RootBridgeHandle = NULL;
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
+
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
+
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);
+
+ if (RootBridgeDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = StartManagingRootBridge (RootBridgeDev);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Determine root bridge attribute by calling interface of Pcihostbridge
+ // protocol
+ //
+ DetermineRootBridgeAttributes (
+ PciResAlloc,
+ RootBridgeDev
+ );
+
+ //
+ // Collect all the resource information under this root bridge
+ // A database that records all the information about pci device subject to this
+ // root bridge will then be created
+ //
+ Status = PciPciDeviceInfoCollector (
+ RootBridgeDev,
+ (UINT8) MinBus
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ InsertRootBridge (RootBridgeDev);
+
+ //
+ // Record the hostbridge handle
+ //
+ AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h new file mode 100644 index 0000000000..1e89445df6 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h @@ -0,0 +1,247 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciLib.h
+
+Abstract:
+
+ PCI Bus Driver Lib header file
+ It abstracts some functions that can be different
+ between light PCI bus driver and full PCI bus driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_LIB_H
+#define _EFI_PCI_LIB_H
+
+VOID
+InstallHotPlugRequestProtocol (
+ IN EFI_STATUS *Status
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Status - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+InstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+UninstallPciHotplugGuid (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+GetBackPcCardBar (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RemoveRejectedPciDevices (
+ EFI_HANDLE RootBridgeHandle,
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ RootBridgeHandle - TODO: add argument description
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeResourceAllocator (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciScanBus (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ StartBusNumber - TODO: add argument description
+ SubBusNumber - TODO: add argument description
+ PaddedBusRange - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciRootBridgeP2CProcess (
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeP2CProcess (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciHostBridgeEnumerator (
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciResAlloc - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c new file mode 100644 index 0000000000..324ad62827 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c @@ -0,0 +1,543 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciOptionRomSupport.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+#include "PciResourceSupport.h"
+
+EFI_STATUS
+GetOpRomInfo (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT8 RomBarIndex;
+ UINT32 AllOnes;
+ UINT64 Address;
+ EFI_STATUS Status;
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ Bus = PciIoDevice->BusNumber;
+ Device = PciIoDevice->DeviceNumber;
+ Function = PciIoDevice->FunctionNumber;
+
+ PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;
+
+ //
+ // offset is 48 if is not ppb
+ //
+
+ //
+ // 0x30
+ //
+ RomBarIndex = PCI_DEVICE_ROMBAR;
+
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
+ //
+ // if is ppb
+ //
+
+ //
+ // 0x38
+ //
+ RomBarIndex = PCI_BRIDGE_ROMBAR;
+ }
+ //
+ // the bit0 is 0 to prevent the enabling of the Rom address decoder
+ //
+ AllOnes = 0xfffffffe;
+ Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &AllOnes
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // read back
+ //
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &AllOnes
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ AllOnes &= 0xFFFFFFFC;
+ if ((AllOnes == 0) || (AllOnes == 0xFFFFFFFC)) {
+ return EFI_NOT_FOUND;
+ }
+
+ PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+LoadOpRomImage (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT64 RomBase
+ )
+/*++
+
+Routine Description:
+
+ Load option rom image for specified PCI device
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: PciDevice - add argument and description to function comment
+// TODO: RomBase - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+{
+ UINT8 RomBarIndex;
+ UINT8 Indicator;
+ UINT16 OffsetPcir;
+ UINT32 RomBarOffset;
+ UINT32 RomBar;
+ UINT64 Temp;
+ EFI_STATUS retStatus;
+ BOOLEAN FirstCheck;
+ UINT8 *Image;
+ PCI_EXPANSION_ROM_HEADER *RomHeader;
+ PCI_DATA_STRUCTURE *RomPcir;
+ UINT64 RomSize;
+ UINT64 RomImageSize;
+ UINT8 *RomInMemory;
+
+ RomSize = PciDevice->RomSize;
+
+ Indicator = 0;
+ RomImageSize = 0;
+ RomInMemory = NULL;
+ Temp = 0;
+
+ //
+ // Get the RomBarIndex
+ //
+
+ //
+ // 0x30
+ //
+ RomBarIndex = PCI_DEVICE_ROMBAR;
+ if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {
+ //
+ // if is ppb
+ //
+
+ //
+ // 0x38
+ //
+ RomBarIndex = PCI_BRIDGE_ROMBAR;
+ }
+ //
+ // Allocate memory for Rom header and PCIR
+ //
+ RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));
+ if (RomHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));
+ if (RomPcir == NULL) {
+ gBS->FreePool (RomHeader);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RomBar = (UINT32) RomBase;
+
+ //
+ // Enable RomBar
+ //
+ RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);
+
+ RomBarOffset = RomBar;
+ retStatus = EFI_NOT_FOUND;
+ FirstCheck = TRUE;
+
+ do {
+ PciDevice->PciRootBridgeIo->Mem.Read (
+ PciDevice->PciRootBridgeIo,
+ EfiPciWidthUint8,
+ RomBarOffset,
+ sizeof (PCI_EXPANSION_ROM_HEADER),
+ (UINT8 *) RomHeader
+ );
+
+ if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+ RomBarOffset = RomBarOffset + 512;
+ if (FirstCheck) {
+ break;
+ } else {
+ RomImageSize = RomImageSize + 512;
+ continue;
+ }
+ }
+
+ FirstCheck = FALSE;
+ OffsetPcir = RomHeader->PcirOffset;
+ PciDevice->PciRootBridgeIo->Mem.Read (
+ PciDevice->PciRootBridgeIo,
+ EfiPciWidthUint8,
+ RomBarOffset + OffsetPcir,
+ sizeof (PCI_DATA_STRUCTURE),
+ (UINT8 *) RomPcir
+ );
+ Indicator = RomPcir->Indicator;
+ RomImageSize = RomImageSize + RomPcir->ImageLength * 512;
+ RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;
+ } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));
+
+ if (RomImageSize > 0) {
+ retStatus = EFI_SUCCESS;
+ Image = AllocatePool ((UINT32) RomImageSize);
+ if (Image == NULL) {
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
+ gBS->FreePool (RomHeader);
+ gBS->FreePool (RomPcir);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy Rom image into memory
+ //
+ PciDevice->PciRootBridgeIo->Mem.Read (
+ PciDevice->PciRootBridgeIo,
+ EfiPciWidthUint8,
+ RomBar,
+ (UINT32) RomImageSize,
+ Image
+ );
+ RomInMemory = Image;
+ }
+
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
+
+ PciDevice->PciIo.RomSize = RomImageSize;
+ PciDevice->PciIo.RomImage = RomInMemory;
+
+ PciRomAddImageMapping (
+ NULL,
+ PciDevice->PciRootBridgeIo->SegmentNumber,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ (UINT64) (UINTN) PciDevice->PciIo.RomImage,
+ PciDevice->PciIo.RomSize
+ );
+
+ //
+ // Free allocated memory
+ //
+ gBS->FreePool (RomHeader);
+ gBS->FreePool (RomPcir);
+
+ return retStatus;
+}
+
+EFI_STATUS
+RomDecode (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT8 RomBarIndex,
+ IN UINT32 RomBar,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: PciDevice - add argument and description to function comment
+// TODO: RomBarIndex - add argument and description to function comment
+// TODO: RomBar - add argument and description to function comment
+// TODO: Enable - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT32 Value32;
+ UINT32 Offset;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ PciIo = &PciDevice->PciIo;
+ if (Enable) {
+ //
+ // Clear all bars
+ //
+ for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);
+ }
+
+ //
+ // set the Rom base address: now is hardcode
+ // enable its decoder
+ //
+ Value32 = RomBar | 0x1;
+ PciIo->Pci.Write (
+ PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,
+ RomBarIndex,
+ 1,
+ &Value32
+ );
+
+ //
+ // Programe all upstream bridge
+ //
+ ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE);
+
+ //
+ // Setting the memory space bit in the function's command register
+ //
+ PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ } else {
+
+ //
+ // disable command register decode to memory
+ //
+ PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ //
+ // Destroy the programmed bar in all the upstream bridge.
+ //
+ ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE);
+
+ //
+ // disable rom decode
+ //
+ Value32 = 0xFFFFFFFE;
+ PciIo->Pci.Write (
+ PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,
+ RomBarIndex,
+ 1,
+ &Value32
+ );
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+ProcessOpRomImage (
+ PCI_IO_DEVICE *PciDevice
+ )
+/*++
+
+Routine Description:
+
+ Process the oprom image.
+
+Arguments:
+ PciDevice A pointer to a pci device.
+
+Returns:
+
+ EFI Status.
+
+--*/
+{
+ UINT8 Indicator;
+ UINT32 ImageSize;
+ UINT16 ImageOffset;
+ VOID *RomBar;
+ UINT8 *RomBarOffset;
+ EFI_HANDLE ImageHandle;
+ EFI_STATUS Status;
+ EFI_STATUS retStatus;
+ BOOLEAN FirstCheck;
+ BOOLEAN SkipImage;
+ UINT32 DestinationSize;
+ UINT32 ScratchSize;
+ UINT8 *Scratch;
+ VOID *ImageBuffer;
+ VOID *DecompressedImageBuffer;
+ UINT32 ImageLength;
+ EFI_DECOMPRESS_PROTOCOL *Decompress;
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
+ PCI_DATA_STRUCTURE *Pcir;
+
+ Indicator = 0;
+
+ //
+ // Get the Address of the Rom image
+ //
+ RomBar = PciDevice->PciIo.RomImage;
+ RomBarOffset = (UINT8 *) RomBar;
+ retStatus = EFI_NOT_FOUND;
+ FirstCheck = TRUE;
+
+ do {
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;
+ if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+ RomBarOffset = RomBarOffset + 512;
+ if (FirstCheck) {
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ FirstCheck = FALSE;
+ Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);
+ ImageSize = (UINT32) (Pcir->ImageLength * 512);
+ Indicator = Pcir->Indicator;
+
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {
+
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {
+
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
+ ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512);
+
+ ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);
+ ImageLength = ImageSize - (UINT32)ImageOffset;
+ DecompressedImageBuffer = NULL;
+
+ //
+ // decompress here if needed
+ //
+ SkipImage = FALSE;
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ SkipImage = TRUE;
+ }
+
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
+ if (EFI_ERROR (Status)) {
+ SkipImage = TRUE;
+ } else {
+ SkipImage = TRUE;
+ Status = Decompress->GetInfo (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ DecompressedImageBuffer = NULL;
+ DecompressedImageBuffer = AllocatePool (DestinationSize);
+ if (DecompressedImageBuffer != NULL) {
+ Scratch = AllocatePool (ScratchSize);
+ if (Scratch != NULL) {
+ Status = Decompress->Decompress (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ DecompressedImageBuffer,
+ DestinationSize,
+ Scratch,
+ ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ ImageBuffer = DecompressedImageBuffer;
+ ImageLength = DestinationSize;
+ SkipImage = FALSE;
+ }
+
+ gBS->FreePool (Scratch);
+ }
+ }
+ }
+ }
+ }
+
+ if (!SkipImage) {
+ //
+ // load image and start image
+ //
+ Status = gBS->LoadImage (
+ FALSE,
+ gPciBusDriverBinding.DriverBindingHandle,
+ PciDevice->Handle,
+ ImageBuffer,
+ ImageLength,
+ &ImageHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ AddDriver (PciDevice, ImageHandle);
+ PciRomAddImageMapping (
+ ImageHandle,
+ PciDevice->PciRootBridgeIo->SegmentNumber,
+ PciDevice->BusNumber,
+ PciDevice->DeviceNumber,
+ PciDevice->FunctionNumber,
+ (UINT64) (UINTN) PciDevice->PciIo.RomImage,
+ PciDevice->PciIo.RomSize
+ );
+ retStatus = EFI_SUCCESS;
+ }
+ }
+ }
+
+ RomBarOffset = RomBarOffset + ImageSize;
+ } else {
+ RomBarOffset = RomBarOffset + ImageSize;
+ }
+ } else {
+ RomBarOffset = RomBarOffset + ImageSize;
+ }
+
+ } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));
+
+ return retStatus;
+
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h new file mode 100644 index 0000000000..2bb11bf3d3 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h @@ -0,0 +1,119 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciOptionRomSupport.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_OP_ROM_SUPPORT_H
+#define _EFI_PCI_OP_ROM_SUPPORT_H
+
+EFI_STATUS
+GetOpRomInfo (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+LoadOpRomImage (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT64 RomBase
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice - TODO: add argument description
+ RomBase - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RomDecode (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT8 RomBarIndex,
+ IN UINT32 RomBar,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice - TODO: add argument description
+ RomBarIndex - TODO: add argument description
+ RomBar - TODO: add argument description
+ Enable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProcessOpRomImage (
+ PCI_IO_DEVICE *PciDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c new file mode 100644 index 0000000000..1760c3946b --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c @@ -0,0 +1,83 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciPowerManagement.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "Pcibus.h"
+
+EFI_STATUS
+ResetPowerManagementFeature (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ This function is intended to turn off PWE assertion and
+ put the device to D0 state if the device supports
+ PCI Power Management.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ UINT8 PowerManagementRegBlock;
+ UINT16 PMCSR;
+
+ PowerManagementRegBlock = 0;
+
+ Status = LocateCapabilityRegBlock (
+ PciIoDevice,
+ EFI_PCI_CAPABILITY_ID_PMI,
+ &PowerManagementRegBlock,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Turn off the PWE assertion and put the device into D0 State
+ //
+ PMCSR = 0x8000;
+
+ //
+ // Write PMCSR
+ //
+ PciIoDevice->PciIo.Pci.Write (
+ &PciIoDevice->PciIo,
+ EfiPciIoWidthUint16,
+ PowerManagementRegBlock + 4,
+ 1,
+ &PMCSR
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h new file mode 100644 index 0000000000..f33f7ab0de --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h @@ -0,0 +1,48 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciPowerManagement.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_POWER_MANAGEMENT_H
+#define _EFI_PCI_POWER_MANAGEMENT_H
+
+EFI_STATUS
+ResetPowerManagementFeature (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c new file mode 100644 index 0000000000..8f89e8983a --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c @@ -0,0 +1,2276 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciResourceSupport.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+#include "PciResourceSupport.h"
+#include "PciCommand.h"
+
+EFI_STATUS
+SkipVGAAperture (
+ OUT UINT64 *Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ The function is used to skip VGA range
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Start - add argument and description to function comment
+// TODO: Length - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT64 Original;
+ UINT64 Mask;
+ UINT64 StartOffset;
+ UINT64 LimitOffset;
+
+ //
+ // For legacy VGA, bit 10 to bit 15 is not decoded
+ //
+ Mask = 0x3FF;
+
+ Original = *Start;
+ StartOffset = Original & Mask;
+ LimitOffset = ((*Start) + Length - 1) & Mask;
+ if (LimitOffset >= VGABASE1) {
+ *Start = *Start - StartOffset + VGALIMIT2 + 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SkipIsaAliasAperture (
+ OUT UINT64 *Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This function is used to skip ISA aliasing aperture
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Start - add argument and description to function comment
+// TODO: Length - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ UINT64 Original;
+ UINT64 Mask;
+ UINT64 StartOffset;
+ UINT64 LimitOffset;
+
+ //
+ // For legacy ISA, bit 10 to bit 15 is not decoded
+ //
+ Mask = 0x3FF;
+
+ Original = *Start;
+ StartOffset = Original & Mask;
+ LimitOffset = ((*Start) + Length - 1) & Mask;
+
+ if (LimitOffset >= ISABASE) {
+ *Start = *Start - StartOffset + ISALIMIT + 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InsertResourceNode (
+ PCI_RESOURCE_NODE *Bridge,
+ PCI_RESOURCE_NODE *ResNode
+ )
+/*++
+
+Routine Description:
+
+ This function inserts a resource node into the resource list.
+ The resource list is sorted in descend order.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: ResNode - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *Temp;
+ UINT64 ResNodeAlignRest;
+ UINT64 TempAlignRest;
+
+ InsertHeadList (&Bridge->ChildList, &ResNode->Link);
+
+ CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;
+ while (CurrentLink != &Bridge->ChildList) {
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (ResNode->Alignment > Temp->Alignment) {
+ break;
+ } else if (ResNode->Alignment == Temp->Alignment) {
+ ResNodeAlignRest = ResNode->Length & ResNode->Alignment;
+ TempAlignRest = Temp->Length & Temp->Alignment;
+ if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {
+ break;
+ }
+ }
+
+ SwapListEntries (&ResNode->Link, CurrentLink);
+
+ CurrentLink = ResNode->Link.ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MergeResourceTree (
+ PCI_RESOURCE_NODE *Dst,
+ PCI_RESOURCE_NODE *Res,
+ BOOLEAN TypeMerge
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to merge two different resource tree in need of
+ resoure degradation. For example, if a upstream PPB doesn't support,
+ prefetchable memory decoding, the PCI bus driver will choose to call this function
+ to merge prefectchable memory resource list into normal memory list.
+
+ If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
+ type.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Dst - add argument and description to function comment
+// TODO: Res - add argument and description to function comment
+// TODO: TypeMerge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *Temp;
+
+ while (!IsListEmpty (&Res->ChildList)) {
+ CurrentLink = Res->ChildList.ForwardLink;
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (TypeMerge) {
+ Temp->ResType = Dst->ResType;
+ }
+
+ RemoveEntryList (CurrentLink);
+ InsertResourceNode (Dst, Temp);
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CalculateApertureIo16 (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ This function is used to calculate the IO16 aperture
+ for a bridge.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ UINT64 Aperture;
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *Node;
+ UINT64 offset;
+
+ //
+ // Always assume there is ISA device and VGA device on the platform
+ // will be customized later
+ //
+ Aperture = 0;
+
+ if (!Bridge) {
+ return EFI_SUCCESS;
+ }
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ //
+ // Assume the bridge is aligned
+ //
+ while (CurrentLink != &Bridge->ChildList) {
+
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ //
+ // Consider the aperture alignment
+ //
+ offset = Aperture & (Node->Alignment);
+
+ if (offset) {
+
+ Aperture = Aperture + (Node->Alignment + 1) - offset;
+
+ }
+
+ //
+ // IsaEnable and VGAEnable can not be implemented now.
+ // If both of them are enabled, then the IO resource would
+ // become too limited to meet the requirement of most of devices.
+ //
+
+ Node->Offset = Aperture;
+
+ //
+ // Increment aperture by the length of node
+ //
+ Aperture += Node->Length;
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // At last, adjust the aperture with the bridge's
+ // alignment
+ //
+ offset = Aperture & (Bridge->Alignment);
+
+ if (offset) {
+ Aperture = Aperture + (Bridge->Alignment + 1) - offset;
+ }
+
+ Bridge->Length = Aperture;
+ //
+ // At last, adjust the bridge's alignment to the first child's alignment
+ // if the bridge has at least one child
+ //
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ if (CurrentLink != &Bridge->ChildList) {
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
+ if (Node->Alignment > Bridge->Alignment) {
+ Bridge->Alignment = Node->Alignment;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CalculateResourceAperture (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ This function is used to calculate the resource aperture
+ for a given bridge device
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ UINT64 Aperture;
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *Node;
+
+ UINT64 offset;
+
+ Aperture = 0;
+
+ if (!Bridge) {
+ return EFI_SUCCESS;
+ }
+
+ if (Bridge->ResType == PciBarTypeIo16) {
+ return CalculateApertureIo16 (Bridge);
+ }
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ //
+ // Assume the bridge is aligned
+ //
+ while (CurrentLink != &Bridge->ChildList) {
+
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ //
+ // Apply padding resource if available
+ //
+
+ offset = Aperture & (Node->Alignment);
+
+ if (offset) {
+
+ Aperture = Aperture + (Node->Alignment + 1) - offset;
+
+ }
+
+ //
+ // Recode current aperture as a offset
+ // this offset will be used in future real allocation
+ //
+ Node->Offset = Aperture;
+
+ //
+ // Increment aperture by the length of node
+ //
+ Aperture += Node->Length;
+
+ //
+ // Consider the aperture alignment
+ //
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // At last, adjust the aperture with the bridge's
+ // alignment
+ //
+ offset = Aperture & (Bridge->Alignment);
+ if (offset) {
+ Aperture = Aperture + (Bridge->Alignment + 1) - offset;
+ }
+
+ //
+ // If the bridge has already padded the resource and the
+ // amount of padded resource is larger, then keep the
+ // padded resource
+ //
+ if (Bridge->Length < Aperture) {
+ Bridge->Length = Aperture;
+ }
+
+ //
+ // At last, adjust the bridge's alignment to the first child's alignment
+ // if the bridge has at least one child
+ //
+ CurrentLink = Bridge->ChildList.ForwardLink;
+ if (CurrentLink != &Bridge->ChildList) {
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
+ if (Node->Alignment > Bridge->Alignment) {
+ Bridge->Alignment = Node->Alignment;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetResourceFromDevice (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDev - add argument and description to function comment
+// TODO: IoNode - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ UINT8 Index;
+ PCI_RESOURCE_NODE *Node;
+ BOOLEAN ResourceRequested;
+
+ Node = NULL;
+ ResourceRequested = FALSE;
+
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {
+
+ switch ((PciDev->PciBar)[Index].BarType) {
+
+ case PciBarTypeMem32:
+
+ Node = CreateResourceNode (
+ PciDev,
+ (PciDev->PciBar)[Index].Length,
+ (PciDev->PciBar)[Index].Alignment,
+ Index,
+ PciBarTypeMem32,
+ PciResUsageTypical
+ );
+
+ InsertResourceNode (
+ Mem32Node,
+ Node
+ );
+
+ ResourceRequested = TRUE;
+ break;
+
+ case PciBarTypeMem64:
+
+ Node = CreateResourceNode (
+ PciDev,
+ (PciDev->PciBar)[Index].Length,
+ (PciDev->PciBar)[Index].Alignment,
+ Index,
+ PciBarTypeMem64,
+ PciResUsageTypical
+ );
+
+ InsertResourceNode (
+ Mem64Node,
+ Node
+ );
+
+ ResourceRequested = TRUE;
+ break;
+
+ case PciBarTypePMem64:
+
+ Node = CreateResourceNode (
+ PciDev,
+ (PciDev->PciBar)[Index].Length,
+ (PciDev->PciBar)[Index].Alignment,
+ Index,
+ PciBarTypePMem64,
+ PciResUsageTypical
+ );
+
+ InsertResourceNode (
+ PMem64Node,
+ Node
+ );
+
+ ResourceRequested = TRUE;
+ break;
+
+ case PciBarTypePMem32:
+
+ Node = CreateResourceNode (
+ PciDev,
+ (PciDev->PciBar)[Index].Length,
+ (PciDev->PciBar)[Index].Alignment,
+ Index,
+ PciBarTypePMem32,
+ PciResUsageTypical
+ );
+
+ InsertResourceNode (
+ PMem32Node,
+ Node
+ );
+ ResourceRequested = TRUE;
+ break;
+
+ case PciBarTypeIo16:
+ case PciBarTypeIo32:
+
+ Node = CreateResourceNode (
+ PciDev,
+ (PciDev->PciBar)[Index].Length,
+ (PciDev->PciBar)[Index].Alignment,
+ Index,
+ PciBarTypeIo16,
+ PciResUsageTypical
+ );
+
+ InsertResourceNode (
+ IoNode,
+ Node
+ );
+ ResourceRequested = TRUE;
+ break;
+
+ case PciBarTypeUnknown:
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ //
+ // If there is no resource requested from this device,
+ // then we indicate this device has been allocated naturally.
+ //
+ if (!ResourceRequested) {
+ PciDev->Allocated = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+PCI_RESOURCE_NODE *
+CreateResourceNode (
+ IN PCI_IO_DEVICE *PciDev,
+ IN UINT64 Length,
+ IN UINT64 Alignment,
+ IN UINT8 Bar,
+ IN PCI_BAR_TYPE ResType,
+ IN PCI_RESOURCE_USAGE ResUsage
+ )
+/*++
+
+Routine Description:
+
+ This function is used to create a resource node
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDev - add argument and description to function comment
+// TODO: Length - add argument and description to function comment
+// TODO: Alignment - add argument and description to function comment
+// TODO: Bar - add argument and description to function comment
+// TODO: ResType - add argument and description to function comment
+// TODO: ResUsage - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ PCI_RESOURCE_NODE *Node;
+
+ Status = 0;
+ Node = NULL;
+
+ Node = AllocatePool (sizeof (PCI_RESOURCE_NODE));
+ if (Node == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));
+
+ Node->Signature = PCI_RESOURCE_SIGNATURE;
+ Node->PciDev = PciDev;
+ Node->Length = Length;
+ Node->Alignment = Alignment;
+ Node->Bar = Bar;
+ Node->ResType = ResType;
+ Node->Reserved = FALSE;
+ Node->ResourceUsage = ResUsage;
+ InitializeListHead (&Node->ChildList);
+ return Node;
+}
+
+EFI_STATUS
+CreateResourceMap (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *IoNode,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to extract resource request from
+ device node list.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: IoNode - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Temp;
+ EFI_STATUS Status;
+ PCI_RESOURCE_NODE *IoBridge;
+ PCI_RESOURCE_NODE *Mem32Bridge;
+ PCI_RESOURCE_NODE *PMem32Bridge;
+ PCI_RESOURCE_NODE *Mem64Bridge;
+ PCI_RESOURCE_NODE *PMem64Bridge;
+ LIST_ENTRY *CurrentLink;
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {
+
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+ //
+ // Create resource nodes for this device by scanning the
+ // Bar array in the device private data
+ // If the upstream bridge doesn't support this device,
+ // no any resource node will be created for this device
+ //
+ GetResourceFromDevice (
+ Temp,
+ IoNode,
+ Mem32Node,
+ PMem32Node,
+ Mem64Node,
+ PMem64Node
+ );
+
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {
+
+ //
+ // If the device has children, create a bridge resource node for this PPB
+ // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
+ // is aligned with 4KB
+ // This device is typically a bridge device like PPB and P2C
+ //
+ IoBridge = CreateResourceNode (
+ Temp,
+ 0,
+ 0xFFF,
+ PPB_IO_RANGE,
+ PciBarTypeIo16,
+ PciResUsageTypical
+ ); //0x1000 aligned
+
+ Mem32Bridge = CreateResourceNode (
+ Temp,
+ 0,
+ 0xFFFFF,
+ PPB_MEM32_RANGE,
+ PciBarTypeMem32,
+ PciResUsageTypical
+ );
+
+ PMem32Bridge = CreateResourceNode (
+ Temp,
+ 0,
+ 0xFFFFF,
+ PPB_PMEM32_RANGE,
+ PciBarTypePMem32,
+ PciResUsageTypical
+ );
+
+ Mem64Bridge = CreateResourceNode (
+ Temp,
+ 0,
+ 0xFFFFF,
+ PPB_MEM64_RANGE,
+ PciBarTypeMem64,
+ PciResUsageTypical
+ );
+
+ PMem64Bridge = CreateResourceNode (
+ Temp,
+ 0,
+ 0xFFFFF,
+ PPB_PMEM64_RANGE,
+ PciBarTypePMem64,
+ PciResUsageTypical
+ );
+
+ //
+ // Recursively create resouce map on this bridge
+ //
+ Status = CreateResourceMap (
+ Temp,
+ IoBridge,
+ Mem32Bridge,
+ PMem32Bridge,
+ Mem64Bridge,
+ PMem64Bridge
+ );
+
+ if (ResourceRequestExisted (IoBridge)) {
+ InsertResourceNode (
+ IoNode,
+ IoBridge
+ );
+ } else {
+ gBS->FreePool (IoBridge);
+ IoBridge = NULL;
+ }
+
+ //
+ // If there is node under this resource bridge,
+ // then calculate bridge's aperture of this type
+ // and insert it into the respective resource tree.
+ // If no, delete this resource bridge
+ //
+ if (ResourceRequestExisted (Mem32Bridge)) {
+ InsertResourceNode (
+ Mem32Node,
+ Mem32Bridge
+ );
+ } else {
+ gBS->FreePool (Mem32Bridge);
+ Mem32Bridge = NULL;
+ }
+
+ //
+ // If there is node under this resource bridge,
+ // then calculate bridge's aperture of this type
+ // and insert it into the respective resource tree.
+ // If no, delete this resource bridge
+ //
+ if (ResourceRequestExisted (PMem32Bridge)) {
+ InsertResourceNode (
+ PMem32Node,
+ PMem32Bridge
+ );
+ } else {
+ gBS->FreePool (PMem32Bridge);
+ PMem32Bridge = NULL;
+ }
+
+ //
+ // If there is node under this resource bridge,
+ // then calculate bridge's aperture of this type
+ // and insert it into the respective resource tree.
+ // If no, delete this resource bridge
+ //
+ if (ResourceRequestExisted (Mem64Bridge)) {
+ InsertResourceNode (
+ Mem64Node,
+ Mem64Bridge
+ );
+ } else {
+ gBS->FreePool (Mem64Bridge);
+ Mem64Bridge = NULL;
+ }
+
+ //
+ // If there is node under this resource bridge,
+ // then calculate bridge's aperture of this type
+ // and insert it into the respective resource tree.
+ // If no, delete this resource bridge
+ //
+ if (ResourceRequestExisted (PMem64Bridge)) {
+ InsertResourceNode (
+ PMem64Node,
+ PMem64Bridge
+ );
+ } else {
+ gBS->FreePool (PMem64Bridge);
+ PMem64Bridge = NULL;
+ }
+
+ }
+
+ //
+ // If it is P2C, apply hard coded resource padding
+ //
+ //
+ if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {
+ ResourcePaddingForCardBusBridge (
+ Temp,
+ IoNode,
+ Mem32Node,
+ PMem32Node,
+ Mem64Node,
+ PMem64Node
+ );
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+ //
+ //
+ // To do some platform specific resource padding ...
+ //
+ Status = ResourcePaddingPolicy (
+ Bridge,
+ IoNode,
+ Mem32Node,
+ PMem32Node,
+ Mem64Node,
+ PMem64Node
+ );
+
+ //
+ // Degrade resource if necessary
+ //
+ DegradeResource (
+ Bridge,
+ Mem32Node,
+ PMem32Node,
+ Mem64Node,
+ PMem64Node
+ );
+
+ //
+ // Calculate resource aperture for this bridge device
+ //
+ CalculateResourceAperture (Mem32Node);
+ CalculateResourceAperture (PMem32Node);
+ CalculateResourceAperture (Mem64Node);
+ CalculateResourceAperture (PMem64Node);
+ CalculateResourceAperture (IoNode);
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+ResourcePaddingPolicy (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ This function is used to do the resource padding for a specific platform
+
+Arguments:
+
+ PciDev - A pointer to the PCI_IO_DEVICE structrue.
+ IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
+ Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
+ PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
+ Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
+ PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
+
+Returns:
+ Status code
+
+ None
+
+--*/
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ //
+ // Create padding resource node
+ //
+ if (PciDev->ResourcePaddingDescriptors != NULL) {
+ ApplyResourcePadding (
+ PciDev,
+ IoNode,
+ Mem32Node,
+ PMem32Node,
+ Mem64Node,
+ PMem64Node
+ );
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+DegradeResource (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ This function is used to degrade resource if the upstream bridge
+ doesn't support certain resource. Degradation path is
+ PMEM64 -> MEM64 -> MEM32
+ PMEM64 -> PMEM32 -> MEM32
+ IO32 -> IO16
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ //
+ // If bridge doesn't support Prefetchable
+ // memory64, degrade it to Mem64
+ //
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {
+ MergeResourceTree (
+ PMem32Node,
+ PMem64Node,
+ TRUE
+ );
+ } else {
+ //
+ // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
+ //
+ if (PMem32Node != NULL) {
+ MergeResourceTree (
+ PMem32Node,
+ PMem64Node,
+ TRUE
+ );
+ }
+ }
+
+
+ //
+ // If bridge doesn't support Mem64
+ // degrade it to mem32
+ //
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {
+ MergeResourceTree (
+ Mem32Node,
+ Mem64Node,
+ TRUE
+ );
+ }
+
+ //
+ // If bridge doesn't support Pmem32
+ // degrade it to mem32
+ //
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {
+ MergeResourceTree (
+ Mem32Node,
+ PMem32Node,
+ TRUE
+ );
+ }
+
+ //
+ // if bridge supports combined Pmem Mem decoding
+ // merge these two type of resource
+ //
+ if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {
+ MergeResourceTree (
+ Mem32Node,
+ PMem32Node,
+ FALSE
+ );
+
+ MergeResourceTree (
+ Mem64Node,
+ PMem64Node,
+ FALSE
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+BridgeSupportResourceDecode (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT32 Decode
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Decode - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ /*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+ if ((Bridge->Decodes) & Decode) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+ProgramResource (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ This function is used to program the resource allocated
+ for each resource node
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Base - add argument and description to function comment
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ LIST_ENTRY *CurrentLink;
+ PCI_RESOURCE_NODE *Node;
+ EFI_STATUS Status;
+
+ if (Base == gAllOne) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ while (CurrentLink != &Bridge->ChildList) {
+
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {
+
+ if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {
+ ProgramP2C (Base, Node);
+ } else {
+ ProgramBar (Base, Node);
+ }
+ } else {
+ Status = ProgramResource (Base + Node->Offset, Node);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ProgramPpbApperture (Base, Node);
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ProgramBar (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Base - add argument and description to function comment
+// TODO: Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 Address;
+ UINT32 Address32;
+
+ Address = 0;
+ PciIo = &(Node->PciDev->PciIo);
+
+ Address = Base + Node->Offset;
+
+ //
+ // Indicate pci bus driver has allocated
+ // resource for this device
+ // It might be a temporary solution here since
+ // pci device could have multiple bar
+ //
+ Node->PciDev->Allocated = TRUE;
+
+ switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {
+
+ case PciBarTypeIo16:
+ case PciBarTypeIo32:
+ case PciBarTypeMem32:
+ case PciBarTypePMem32:
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ (Node->PciDev->PciBar[Node->Bar]).Offset,
+ 1,
+ &Address
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+
+ break;
+
+ case PciBarTypeMem64:
+ case PciBarTypePMem64:
+
+ Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ (Node->PciDev->PciBar[Node->Bar]).Offset,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) RShiftU64 (Address, 32);
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),
+ 1,
+ &Address32
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ProgramPpbApperture (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Base - add argument and description to function comment
+// TODO: Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 Address;
+ UINT32 Address32;
+
+ Address = 0;
+ //
+ // if no device south of this PPB, return anyway
+ // Apperture is set default in the initialization code
+ //
+ if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {
+ //
+ // For padding resource node, just ignore when programming
+ //
+ return EFI_SUCCESS;
+ }
+
+ PciIo = &(Node->PciDev->PciIo);
+ Address = Base + Node->Offset;
+
+ //
+ // Indicate the PPB resource has been allocated
+ //
+ Node->PciDev->Allocated = TRUE;
+
+ switch (Node->Bar) {
+
+ case PPB_BAR_0:
+ case PPB_BAR_1:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ (Node->PciDev->PciBar[Node->Bar]).Offset,
+ 1,
+ &Address
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+
+ break;
+
+ case PPB_IO_RANGE:
+
+ Address32 = ((UINT32) (Address)) >> 8;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0x1C,
+ 1,
+ &Address32
+ );
+
+ Address32 >>= 8;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x30,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) (Address + Node->Length - 1);
+ Address32 = ((UINT32) (Address32)) >> 8;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0x1D,
+ 1,
+ &Address32
+ );
+
+ Address32 >>= 8;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x32,
+ 1,
+ &Address32
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ break;
+
+ case PPB_MEM32_RANGE:
+
+ Address32 = ((UINT32) (Address)) >> 16;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x20,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) (Address + Node->Length - 1);
+ Address32 = ((UINT32) (Address32)) >> 16;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x22,
+ 1,
+ &Address32
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ break;
+
+ case PPB_PMEM32_RANGE:
+ case PPB_PMEM64_RANGE:
+
+ Address32 = ((UINT32) (Address)) >> 16;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x24,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) (Address + Node->Length - 1);
+ Address32 = ((UINT32) (Address32)) >> 16;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x26,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) RShiftU64 (Address, 32);
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x28,
+ 1,
+ &Address32
+ );
+
+ Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x2C,
+ 1,
+ &Address32
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ProgrameUpstreamBridgeForRom (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT32 OptionRomBase,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: PciDevice - add argument and description to function comment
+// TODO: OptionRomBase - add argument and description to function comment
+// TODO: Enable - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_IO_DEVICE *Parent;
+ PCI_RESOURCE_NODE Node;
+ //
+ // For root bridge, just return.
+ //
+ Parent = PciDevice->Parent;
+ ZeroMem (&Node, sizeof (Node));
+ while (Parent) {
+ if (!IS_PCI_BRIDGE (&Parent->Pci)) {
+ break;
+ }
+
+ Node.PciDev = Parent;
+ Node.Length = PciDevice->RomSize;
+ Node.Alignment = 0;
+ Node.Bar = PPB_MEM32_RANGE;
+ Node.ResType = PciBarTypeMem32;
+ Node.Offset = 0;
+
+ //
+ // Program PPB to only open a single <= 16<MB apperture
+ //
+ if (Enable) {
+ ProgramPpbApperture (OptionRomBase, &Node);
+ PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);
+ } else {
+ InitializePpb (Parent);
+ PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);
+ }
+
+ Parent = Parent->Parent;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+ResourceRequestExisted (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ Bridge - A pointer to the PCI_RESOURCE_NODE.
+
+Returns:
+
+ None
+
+--*/
+{
+ if (Bridge != NULL) {
+ if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+InitializeResourcePool (
+ PCI_RESOURCE_NODE *ResourcePool,
+ PCI_BAR_TYPE ResourceType
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: ResourcePool - add argument and description to function comment
+// TODO: ResourceType - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));
+ ResourcePool->ResType = ResourceType;
+ ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;
+ InitializeListHead (&ResourcePool->ChildList);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetResourceMap (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE **IoBridge,
+ PCI_RESOURCE_NODE **Mem32Bridge,
+ PCI_RESOURCE_NODE **PMem32Bridge,
+ PCI_RESOURCE_NODE **Mem64Bridge,
+ PCI_RESOURCE_NODE **PMem64Bridge,
+ PCI_RESOURCE_NODE *IoPool,
+ PCI_RESOURCE_NODE *Mem32Pool,
+ PCI_RESOURCE_NODE *PMem32Pool,
+ PCI_RESOURCE_NODE *Mem64Pool,
+ PCI_RESOURCE_NODE *PMem64Pool
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDev - add argument and description to function comment
+// TODO: IoBridge - add argument and description to function comment
+// TODO: Mem32Bridge - add argument and description to function comment
+// TODO: PMem32Bridge - add argument and description to function comment
+// TODO: Mem64Bridge - add argument and description to function comment
+// TODO: PMem64Bridge - add argument and description to function comment
+// TODO: IoPool - add argument and description to function comment
+// TODO: Mem32Pool - add argument and description to function comment
+// TODO: PMem32Pool - add argument and description to function comment
+// TODO: Mem64Pool - add argument and description to function comment
+// TODO: PMem64Pool - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+
+ PCI_RESOURCE_NODE *Temp;
+ LIST_ENTRY *CurrentLink;
+
+ CurrentLink = IoPool->ChildList.ForwardLink;
+
+ //
+ // Get Io resource map
+ //
+ while (CurrentLink != &IoPool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciDev == PciDev) {
+ *IoBridge = Temp;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Get Mem32 resource map
+ //
+ CurrentLink = Mem32Pool->ChildList.ForwardLink;
+
+ while (CurrentLink != &Mem32Pool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciDev == PciDev) {
+ *Mem32Bridge = Temp;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Get Pmem32 resource map
+ //
+ CurrentLink = PMem32Pool->ChildList.ForwardLink;
+
+ while (CurrentLink != &PMem32Pool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciDev == PciDev) {
+ *PMem32Bridge = Temp;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Get Mem64 resource map
+ //
+ CurrentLink = Mem64Pool->ChildList.ForwardLink;
+
+ while (CurrentLink != &Mem64Pool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciDev == PciDev) {
+ *Mem64Bridge = Temp;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Get Pmem64 resource map
+ //
+ CurrentLink = PMem64Pool->ChildList.ForwardLink;
+
+ while (CurrentLink != &PMem64Pool->ChildList) {
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ if (Temp->PciDev == PciDev) {
+ *PMem64Bridge = Temp;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyResourceTree (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_RESOURCE_NODE *Temp;
+ LIST_ENTRY *CurrentLink;
+
+ while (!IsListEmpty (&Bridge->ChildList)) {
+
+ CurrentLink = Bridge->ChildList.ForwardLink;
+
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
+
+ RemoveEntryList (CurrentLink);
+
+ if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {
+ DestroyResourceTree (Temp);
+ }
+
+ gBS->FreePool (Temp);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RecordReservedResource (
+ IN UINT64 Base,
+ IN UINT64 Length,
+ IN PCI_BAR_TYPE ResType,
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Base - add argument and description to function comment
+// TODO: Length - add argument and description to function comment
+// TODO: ResType - add argument and description to function comment
+// TODO: Bridge - add argument and description to function comment
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_RESERVED_RESOURCE_LIST *ReservedNode;
+
+ ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));
+ if (ReservedNode == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;
+ ReservedNode->Node.Base = Base;
+ ReservedNode->Node.Length = Length;
+ ReservedNode->Node.ResType = ResType;
+
+ InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ResourcePaddingForCardBusBridge (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDev - add argument and description to function comment
+// TODO: IoNode - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ PCI_RESOURCE_NODE *Node;
+
+ Node = NULL;
+
+ //
+ // Memory Base/Limit Register 0
+ // Bar 1 denodes memory range 0
+ //
+ Node = CreateResourceNode (
+ PciDev,
+ 0x2000000,
+ 0x1ffffff,
+ 1,
+ PciBarTypeMem32,
+ PciResUsagePadding
+ );
+
+ InsertResourceNode (
+ Mem32Node,
+ Node
+ );
+
+ //
+ // Memory Base/Limit Register 1
+ // Bar 2 denodes memory range1
+ //
+ Node = CreateResourceNode (
+ PciDev,
+ 0x2000000,
+ 0x1ffffff,
+ 2,
+ PciBarTypePMem32,
+ PciResUsagePadding
+ );
+
+ InsertResourceNode (
+ PMem32Node,
+ Node
+ );
+
+ //
+ // Io Base/Limit
+ // Bar 3 denodes io range 0
+ //
+ Node = CreateResourceNode (
+ PciDev,
+ 0x100,
+ 0xff,
+ 3,
+ PciBarTypeIo16,
+ PciResUsagePadding
+ );
+
+ InsertResourceNode (
+ IoNode,
+ Node
+ );
+
+ //
+ // Io Base/Limit
+ // Bar 4 denodes io range 0
+ //
+ Node = CreateResourceNode (
+ PciDev,
+ 0x100,
+ 0xff,
+ 4,
+ PciBarTypeIo16,
+ PciResUsagePadding
+ );
+
+ InsertResourceNode (
+ IoNode,
+ Node
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ProgramP2C (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: Base - add argument and description to function comment
+// TODO: Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 Address;
+ UINT64 TempAddress;
+ UINT16 BridgeControl;
+
+ Address = 0;
+ PciIo = &(Node->PciDev->PciIo);
+
+ Address = Base + Node->Offset;
+
+ //
+ // Indicate pci bus driver has allocated
+ // resource for this device
+ // It might be a temporary solution here since
+ // pci device could have multiple bar
+ //
+ Node->PciDev->Allocated = TRUE;
+
+ switch (Node->Bar) {
+
+ case P2C_BAR_0:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ (Node->PciDev->PciBar[Node->Bar]).Offset,
+ 1,
+ &Address
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ break;
+
+ case P2C_MEM_1:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x1c,
+ 1,
+ &Address
+ );
+
+ TempAddress = Address + Node->Length - 1;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x20,
+ 1,
+ &TempAddress
+ );
+
+ if (Node->ResType == PciBarTypeMem32) {
+
+ //
+ // Set non-prefetchable bit
+ //
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+
+ BridgeControl &= 0xfeff;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+
+ } else {
+
+ //
+ // Set pre-fetchable bit
+ //
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+
+ BridgeControl |= 0x0100;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+ }
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;
+
+ break;
+
+ case P2C_MEM_2:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x24,
+ 1,
+ &Address
+ );
+
+ TempAddress = Address + Node->Length - 1;
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x28,
+ 1,
+ &TempAddress
+ );
+
+ if (Node->ResType == PciBarTypeMem32) {
+
+ //
+ // Set non-prefetchable bit
+ //
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+
+ BridgeControl &= 0xfdff;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+ } else {
+
+ //
+ // Set pre-fetchable bit
+ //
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+
+ BridgeControl |= 0x0200;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ 0x3e,
+ 1,
+ &BridgeControl
+ );
+ }
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;
+ break;
+
+ case P2C_IO_1:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x2c,
+ 1,
+ &Address
+ );
+ TempAddress = Address + Node->Length - 1;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x30,
+ 1,
+ &TempAddress
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;
+
+ break;
+
+ case P2C_IO_2:
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x34,
+ 1,
+ &Address
+ );
+
+ TempAddress = Address + Node->Length - 1;
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0x38,
+ 1,
+ &TempAddress
+ );
+
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ApplyResourcePadding (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+// TODO: PciDev - add argument and description to function comment
+// TODO: IoNode - add argument and description to function comment
+// TODO: Mem32Node - add argument and description to function comment
+// TODO: PMem32Node - add argument and description to function comment
+// TODO: Mem64Node - add argument and description to function comment
+// TODO: PMem64Node - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+ PCI_RESOURCE_NODE *Node;
+ UINT8 DummyBarIndex;
+
+ DummyBarIndex = 0;
+ Ptr = PciDev->ResourcePaddingDescriptors;
+
+ while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {
+
+ if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {
+ if (Ptr->AddrLen != 0) {
+
+ Node = CreateResourceNode (
+ PciDev,
+ Ptr->AddrLen,
+ Ptr->AddrRangeMax,
+ DummyBarIndex,
+ PciBarTypeIo16,
+ PciResUsagePadding
+ );
+ InsertResourceNode (
+ IoNode,
+ Node
+ );
+ }
+
+ Ptr++;
+ continue;
+ }
+
+ if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+
+ if (Ptr->AddrSpaceGranularity == 32) {
+
+ //
+ // prefechable
+ //
+ if (Ptr->SpecificFlag == 0x6) {
+ if (Ptr->AddrLen) {
+ Node = CreateResourceNode (
+ PciDev,
+ Ptr->AddrLen,
+ Ptr->AddrRangeMax,
+ DummyBarIndex,
+ PciBarTypePMem32,
+ PciResUsagePadding
+ );
+ InsertResourceNode (
+ PMem32Node,
+ Node
+ );
+ }
+
+ Ptr++;
+ continue;
+ }
+
+ //
+ // Non-prefechable
+ //
+ if (Ptr->SpecificFlag == 0) {
+ if (Ptr->AddrLen) {
+ Node = CreateResourceNode (
+ PciDev,
+ Ptr->AddrLen,
+ Ptr->AddrRangeMax,
+ DummyBarIndex,
+ PciBarTypeMem32,
+ PciResUsagePadding
+ );
+ InsertResourceNode (
+ Mem32Node,
+ Node
+ );
+ }
+
+ Ptr++;
+ continue;
+ }
+ }
+
+ if (Ptr->AddrSpaceGranularity == 64) {
+
+ //
+ // prefechable
+ //
+ if (Ptr->SpecificFlag == 0x6) {
+ if (Ptr->AddrLen) {
+ Node = CreateResourceNode (
+ PciDev,
+ Ptr->AddrLen,
+ Ptr->AddrRangeMax,
+ DummyBarIndex,
+ PciBarTypePMem64,
+ PciResUsagePadding
+ );
+ InsertResourceNode (
+ PMem64Node,
+ Node
+ );
+ }
+
+ Ptr++;
+ continue;
+ }
+
+ //
+ // Non-prefechable
+ //
+ if (Ptr->SpecificFlag == 0) {
+ if (Ptr->AddrLen) {
+ Node = CreateResourceNode (
+ PciDev,
+ Ptr->AddrLen,
+ Ptr->AddrRangeMax,
+ DummyBarIndex,
+ PciBarTypeMem64,
+ PciResUsagePadding
+ );
+ InsertResourceNode (
+ Mem64Node,
+ Node
+ );
+ }
+
+ Ptr++;
+ continue;
+ }
+ }
+ }
+
+ Ptr++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Light PCI bus driver woundn't support hotplug root device
+// So no need to pad resource for them
+//
+VOID
+GetResourcePaddingPpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ Get resource.
+
+Arguments:
+
+ PciIoDevice A pointer to a pci device.
+
+Returns:
+
+ None
+
+--*/
+{
+ if (gPciHotPlugInit) {
+ if (PciIoDevice->ResourcePaddingDescriptors == NULL) {
+ GetResourcePaddingForHpb (PciIoDevice);
+ }
+ }
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h new file mode 100644 index 0000000000..61ec29f7ec --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h @@ -0,0 +1,740 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciResourceSupport.h
+
+Abstract:
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_RESOURCE_SUPPORT_H
+#define _EFI_PCI_RESOURCE_SUPPORT_H
+
+#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd')
+
+typedef struct {
+ UINT64 Base;
+ UINT64 Length;
+ PCI_BAR_TYPE ResType;
+} PCI_RESERVED_RESOURCE_NODE;
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ PCI_RESERVED_RESOURCE_NODE Node;
+} PCI_RESERVED_RESOURCE_LIST;
+
+#define RESOURCED_LIST_FROM_NODE(a) \
+ CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE)
+
+#define RESOURCED_LIST_FROM_LINK(a) \
+ CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE)
+
+typedef enum {
+ PciResUsageTypical = 0,
+ PciResUsagePadding,
+ PciResUsageOptionRomProcessing
+} PCI_RESOURCE_USAGE;
+
+#define PCI_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'r', 'c')
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ LIST_ENTRY ChildList;
+ PCI_IO_DEVICE *PciDev;
+ UINT64 Alignment;
+ UINT64 Offset;
+ UINT8 Bar;
+ PCI_BAR_TYPE ResType;
+ UINT64 Length;
+ BOOLEAN Reserved;
+ PCI_RESOURCE_USAGE ResourceUsage;
+} PCI_RESOURCE_NODE;
+
+#define RESOURCE_NODE_FROM_LINK(a) \
+ CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE)
+
+EFI_STATUS
+SkipVGAAperture (
+ OUT UINT64 *Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Start - TODO: add argument description
+ Length - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+SkipIsaAliasAperture (
+ OUT UINT64 *Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Start - TODO: add argument description
+ Length - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InsertResourceNode (
+ PCI_RESOURCE_NODE *Bridge,
+ PCI_RESOURCE_NODE *ResNode
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ ResNode - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+MergeResourceTree (
+ PCI_RESOURCE_NODE *Dst,
+ PCI_RESOURCE_NODE *Res,
+ BOOLEAN TypeMerge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Dst - TODO: add argument description
+ Res - TODO: add argument description
+ TypeMerge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CalculateApertureIo16 (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CalculateResourceAperture (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourceFromDevice (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+PCI_RESOURCE_NODE *
+CreateResourceNode (
+ IN PCI_IO_DEVICE *PciDev,
+ IN UINT64 Length,
+ IN UINT64 Alignment,
+ IN UINT8 Bar,
+ IN PCI_BAR_TYPE ResType,
+ IN PCI_RESOURCE_USAGE ResUsage
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ Length - TODO: add argument description
+ Alignment - TODO: add argument description
+ Bar - TODO: add argument description
+ ResType - TODO: add argument description
+ ResUsage - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CreateResourceMap (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *IoNode,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ResourcePaddingPolicy (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DegradeResource (
+ IN PCI_IO_DEVICE *Bridge,
+ IN PCI_RESOURCE_NODE *Mem32Node,
+ IN PCI_RESOURCE_NODE *PMem32Node,
+ IN PCI_RESOURCE_NODE *Mem64Node,
+ IN PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+BridgeSupportResourceDecode (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT32 Decode
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+ Decode - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProgramResource (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Base - TODO: add argument description
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProgramBar (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Base - TODO: add argument description
+ Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProgramPpbApperture (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Base - TODO: add argument description
+ Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProgrameUpstreamBridgeForRom (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINT32 OptionRomBase,
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDevice - TODO: add argument description
+ OptionRomBase - TODO: add argument description
+ Enable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ResourceRequestExisted (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+InitializeResourcePool (
+ PCI_RESOURCE_NODE *ResourcePool,
+ PCI_BAR_TYPE ResourceType
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ResourcePool - TODO: add argument description
+ ResourceType - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetResourceMap (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE **IoBridge,
+ PCI_RESOURCE_NODE **Mem32Bridge,
+ PCI_RESOURCE_NODE **PMem32Bridge,
+ PCI_RESOURCE_NODE **Mem64Bridge,
+ PCI_RESOURCE_NODE **PMem64Bridge,
+ PCI_RESOURCE_NODE *IoPool,
+ PCI_RESOURCE_NODE *Mem32Pool,
+ PCI_RESOURCE_NODE *PMem32Pool,
+ PCI_RESOURCE_NODE *Mem64Pool,
+ PCI_RESOURCE_NODE *PMem64Pool
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ IoBridge - TODO: add argument description
+ Mem32Bridge - TODO: add argument description
+ PMem32Bridge - TODO: add argument description
+ Mem64Bridge - TODO: add argument description
+ PMem64Bridge - TODO: add argument description
+ IoPool - TODO: add argument description
+ Mem32Pool - TODO: add argument description
+ PMem32Pool - TODO: add argument description
+ Mem64Pool - TODO: add argument description
+ PMem64Pool - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DestroyResourceTree (
+ IN PCI_RESOURCE_NODE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+RecordReservedResource (
+ IN UINT64 Base,
+ IN UINT64 Length,
+ IN PCI_BAR_TYPE ResType,
+ IN PCI_IO_DEVICE *Bridge
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Base - TODO: add argument description
+ Length - TODO: add argument description
+ ResType - TODO: add argument description
+ Bridge - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ResourcePaddingForCardBusBridge (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ProgramP2C (
+ IN UINT64 Base,
+ IN PCI_RESOURCE_NODE *Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Base - TODO: add argument description
+ Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ApplyResourcePadding (
+ PCI_IO_DEVICE *PciDev,
+ PCI_RESOURCE_NODE *IoNode,
+ PCI_RESOURCE_NODE *Mem32Node,
+ PCI_RESOURCE_NODE *PMem32Node,
+ PCI_RESOURCE_NODE *Mem64Node,
+ PCI_RESOURCE_NODE *PMem64Node
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciDev - TODO: add argument description
+ IoNode - TODO: add argument description
+ Mem32Node - TODO: add argument description
+ PMem32Node - TODO: add argument description
+ Mem64Node - TODO: add argument description
+ PMem64Node - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+GetResourcePaddingPpb (
+ IN PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ResetAllPpbBusReg (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber
+ )
+/*++
+
+Routine Description:
+
+ Reset bus register
+
+Arguments:
+
+ Bridge - a pointer to the PCI_IO_DEVICE
+ StartBusNumber - the number of bus
+
+Returns:
+
+ None
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c new file mode 100644 index 0000000000..a1e16a0eea --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c @@ -0,0 +1,457 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciRomTable.c
+
+Abstract:
+
+ Option Rom Support for PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "pcibus.h"
+#include "PciRomTable.h"
+
+typedef struct {
+ EFI_HANDLE ImageHandle;
+ UINTN Seg;
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Func;
+ UINT64 RomAddress;
+ UINT64 RomLength;
+} EFI_PCI_ROM_IMAGE_MAPPING;
+
+static UINTN mNumberOfPciRomImages = 0;
+static UINTN mMaxNumberOfPciRomImages = 0;
+static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;
+
+VOID
+PciRomAddImageMapping (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN Seg,
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Func,
+ IN UINT64 RomAddress,
+ IN UINT64 RomLength
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ Seg - TODO: add argument description
+ Bus - TODO: add argument description
+ Dev - TODO: add argument description
+ Func - TODO: add argument description
+ RomAddress - TODO: add argument description
+ RomLength - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;
+
+ if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {
+
+ mMaxNumberOfPciRomImages += 0x20;
+
+ TempMapping = NULL;
+ TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
+ if (TempMapping == NULL) {
+ return ;
+ }
+
+ CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
+
+ if (mRomImageTable != NULL) {
+ gBS->FreePool (mRomImageTable);
+ }
+
+ mRomImageTable = TempMapping;
+ }
+
+ mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;
+ mRomImageTable[mNumberOfPciRomImages].Seg = Seg;
+ mRomImageTable[mNumberOfPciRomImages].Bus = Bus;
+ mRomImageTable[mNumberOfPciRomImages].Dev = Dev;
+ mRomImageTable[mNumberOfPciRomImages].Func = Func;
+ mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress;
+ mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength;
+ mNumberOfPciRomImages++;
+}
+
+VOID
+HexToString (
+ CHAR16 *String,
+ UINTN Value,
+ UINTN Digits
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ String - TODO: add argument description
+ Value - TODO: add argument description
+ Digits - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ for (; Digits > 0; Digits--, String++) {
+ *String = (CHAR16) ((Value >> (4 * (Digits - 1))) & 0x0f);
+ if (*String > 9) {
+ (*String) += ('A' - 10);
+ } else {
+ (*String) += '0';
+ }
+ }
+}
+EFI_STATUS
+PciRomLoadEfiDriversFromRomImage (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: PciOptionRomDescriptor - add argument and description to function comment
+{
+ VOID *RomBar;
+ UINTN RomSize;
+ CHAR16 *FileName;
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
+ PCI_DATA_STRUCTURE *Pcir;
+ UINTN ImageIndex;
+ UINTN RomBarOffset;
+ UINT32 ImageSize;
+ UINT16 ImageOffset;
+ EFI_HANDLE ImageHandle;
+ EFI_STATUS Status;
+ EFI_STATUS retStatus;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ BOOLEAN SkipImage;
+ UINT32 DestinationSize;
+ UINT32 ScratchSize;
+ UINT8 *Scratch;
+ VOID *ImageBuffer;
+ VOID *DecompressedImageBuffer;
+ UINT32 ImageLength;
+ EFI_DECOMPRESS_PROTOCOL *Decompress;
+
+ RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
+ RomSize = (UINTN) PciOptionRomDescriptor->RomLength;
+ FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";
+
+ HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);
+ HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);
+ HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);
+ HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);
+
+ ImageIndex = 0;
+ retStatus = EFI_NOT_FOUND;
+ RomBarOffset = (UINTN) RomBar;
+
+ do {
+
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;
+
+ if (EfiRomHeader->Signature != 0xaa55) {
+ return retStatus;
+ }
+
+ Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);
+ ImageSize = Pcir->ImageLength * 512;
+
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {
+
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {
+
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
+ ImageSize = EfiRomHeader->InitializationSize * 512;
+
+ ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);
+ ImageLength = ImageSize - ImageOffset;
+ DecompressedImageBuffer = NULL;
+
+ //
+ // decompress here if needed
+ //
+ SkipImage = FALSE;
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ SkipImage = TRUE;
+ }
+
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
+ if (EFI_ERROR (Status)) {
+ SkipImage = TRUE;
+ } else {
+ SkipImage = TRUE;
+ Status = Decompress->GetInfo (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ DecompressedImageBuffer = NULL;
+ DecompressedImageBuffer = AllocatePool (DestinationSize);
+ if (DecompressedImageBuffer != NULL) {
+ Scratch = AllocatePool (ScratchSize);
+ if (Scratch != NULL) {
+ Status = Decompress->Decompress (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ DecompressedImageBuffer,
+ DestinationSize,
+ Scratch,
+ ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ ImageBuffer = DecompressedImageBuffer;
+ ImageLength = DestinationSize;
+ SkipImage = FALSE;
+ }
+
+ gBS->FreePool (Scratch);
+ }
+ }
+ }
+ }
+ }
+
+ if (!SkipImage) {
+
+ //
+ // load image and start image
+ //
+
+ HexToString (&FileName[48], ImageIndex, 4);
+ FilePath = FileDevicePath (NULL, FileName);
+
+ Status = gBS->LoadImage (
+ FALSE,
+ This->ImageHandle,
+ FilePath,
+ ImageBuffer,
+ ImageLength,
+ &ImageHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ PciRomAddImageMapping (
+ ImageHandle,
+ PciOptionRomDescriptor->Seg,
+ PciOptionRomDescriptor->Bus,
+ PciOptionRomDescriptor->Dev,
+ PciOptionRomDescriptor->Func,
+ PciOptionRomDescriptor->RomAddress,
+ PciOptionRomDescriptor->RomLength
+ );
+ retStatus = Status;
+ }
+ }
+ }
+
+ if (DecompressedImageBuffer != NULL) {
+ gBS->FreePool (DecompressedImageBuffer);
+ }
+
+ }
+ }
+
+ RomBarOffset = RomBarOffset + ImageSize;
+ ImageIndex++;
+ } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));
+
+ return retStatus;
+}
+
+EFI_STATUS
+PciRomLoadEfiDriversFromOptionRomTable (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;
+ EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
+ UINTN Index;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
+ UINT16 MinBus;
+ UINT16 MaxBus;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
+ PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
+ if (!PciOptionRomDescriptor->DontLoadEfiRom) {
+ if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);
+ if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {
+ Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);
+ PciOptionRomDescriptor->DontLoadEfiRom |= 2;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+PciRomGetRomResourceFromPciOptionRomTable (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;
+ EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
+ UINTN Index;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
+ PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
+ if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&
+ PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&
+ PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&
+ PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {
+
+ PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
+ PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;
+ }
+ }
+
+ for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
+ if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&
+ mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&
+ mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&
+ mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
+
+ AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRomGetImageMapping (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// TODO: PciIoDevice - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ UINTN Index;
+
+ PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;
+
+ for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
+ if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&
+ mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&
+ mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&
+ mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
+
+ if (mRomImageTable[Index].ImageHandle != NULL) {
+ AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
+ } else {
+ PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress;
+ PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h new file mode 100644 index 0000000000..bb20c70156 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h @@ -0,0 +1,107 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciRomTable.h
+
+Abstract:
+
+ Option Rom Support for PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_ROM_TABLE_H
+#define _EFI_PCI_ROM_TABLE_H
+
+VOID
+PciRomAddImageMapping (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN Seg,
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Func,
+ IN UINT64 RomAddress,
+ IN UINT64 RomLength
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ Seg - TODO: add argument description
+ Bus - TODO: add argument description
+ Dev - TODO: add argument description
+ Func - TODO: add argument description
+ RomAddress - TODO: add argument description
+ RomLength - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+
+EFI_STATUS
+PciRomGetRomResourceFromPciOptionRomTable (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ PciRootBridgeIo - TODO: add argument description
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+PciRomGetImageMapping (
+ PCI_IO_DEVICE *PciIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ PciIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml b/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml new file mode 100644 index 0000000000..ee051c7231 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<project basedir="." default="PciBus"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Bus\Pci\PciBus\Dxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="PciBus">
+ <GenBuild baseName="PciBus" mbdFilename="${MODULE_DIR}\PciBus.mbd" msaFilename="${MODULE_DIR}\PciBus.msa"/>
+ </target>
+ <target name="LightPciBusPciBus">
+ <GenBuild baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}\LightPciBus.mbd" msaFilename="${MODULE_DIR}\LightPciBus.msa"/>
+ </target>
+ <target name="PciBusPciBusLite">
+ <GenBuild baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}\PciBusLite.mbd" msaFilename="${MODULE_DIR}\PciBusLite.msa"/>
+ </target>
+ <target depends="PciBus_clean" name="clean"/>
+ <target depends="PciBus_cleanall" name="cleanall"/>
+ <target name="PciBus_clean">
+ <OutputDirSetup baseName="PciBus" mbdFilename="${MODULE_DIR}\PciBus.mbd" msaFilename="${MODULE_DIR}\PciBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PciBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PciBus_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="LightPciBusPciBus_clean">
+ <OutputDirSetup baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}\LightPciBus.mbd" msaFilename="${MODULE_DIR}\LightPciBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\LightPciBusPciBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\LightPciBusPciBus_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="PciBusPciBusLite_clean">
+ <OutputDirSetup baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}\PciBusLite.mbd" msaFilename="${MODULE_DIR}\PciBusLite.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PciBusPciBusLite_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PciBusPciBusLite_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="PciBus_cleanall">
+ <OutputDirSetup baseName="PciBus" mbdFilename="${MODULE_DIR}\PciBus.mbd" msaFilename="${MODULE_DIR}\PciBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PciBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PciBus_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**PciBus*"/>
+ </delete>
+ </target>
+ <target name="LightPciBusPciBus_cleanall">
+ <OutputDirSetup baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}\LightPciBus.mbd" msaFilename="${MODULE_DIR}\LightPciBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\LightPciBusPciBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\LightPciBusPciBus_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**LightPciBusPciBus*"/>
+ </delete>
+ </target>
+ <target name="PciBusPciBusLite_cleanall">
+ <OutputDirSetup baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}\PciBusLite.mbd" msaFilename="${MODULE_DIR}\PciBusLite.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PciBusPciBusLite_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PciBusPciBusLite_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**PciBusPciBusLite*"/>
+ </delete>
+ </target>
+</project>
\ No newline at end of file diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c new file mode 100644 index 0000000000..16a33010e4 --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c @@ -0,0 +1,375 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciBus.c
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#include "PciBus.h"
+
+//
+// PCI Bus Support Function Prototypes
+//
+
+EFI_STATUS
+EFIAPI
+PciBusEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// PCI Bus Driver Global Variables
+//
+
+EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
+ PciBusDriverBindingSupported,
+ PciBusDriverBindingStart,
+ PciBusDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport = NULL;
+EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
+UINTN gPciHostBridgeNumber;
+BOOLEAN gFullEnumeration;
+UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
+UINT64 gAllZero = 0;
+
+EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
+
+//
+// PCI Bus Driver Support Functions
+//
+EFI_STATUS
+EFIAPI
+PciBusEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Initialize the global variables
+ publish the driver binding protocol
+
+Arguments:
+
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+// TODO: ImageHandle - add argument and description to function comment
+// TODO: SystemTable - add argument and description to function comment
+{
+ EFI_STATUS Status;
+
+ InitializePciDevicePool ();
+
+ gFullEnumeration = TRUE;
+
+ gPciHostBridgeNumber = 0;
+
+ InstallHotPlugRequestProtocol (&Status);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ Check to see if pci bus driver supports the given controller
+
+Arguments:
+
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_DEV_PATH_PTR Node;
+
+ if (RemainingDevicePath != NULL) {
+ Node.DevPath = RemainingDevicePath;
+ if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
+ Node.DevPath->SubType != HW_PCI_DP ||
+ DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ (VOID **) &PciRootBridgeIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ Start to management the controller passed in
+
+Arguments:
+
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+
+Returns:
+
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ &gEfiIncompatiblePciDeviceSupportProtocolGuid,
+ NULL,
+ (VOID **) &gEfiIncompatiblePciDeviceSupport
+ );
+
+ //
+ // If PCI Platform protocol is available, get it now.
+ // If the platform implements this, it must be installed before BDS phase
+ //
+ gPciPlatformProtocol = NULL;
+ gBS->LocateProtocol (
+ &gEfiPciPlatformProtocolGuid,
+ NULL,
+ (VOID **) &gPciPlatformProtocol
+ );
+
+ gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
+
+ //
+ // Enumerate the entire host bridge
+ // After enumeration, a database that records all the device information will be created
+ //
+ //
+ Status = PciEnumerator (Controller);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Enable PCI device specified by remaining device path. BDS or other driver can call the
+ // start more than once.
+ //
+
+ StartPciDevices (Controller, RemainingDevicePath);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ Stop one or more children created at start of pci bus driver
+ if all the the children get closed, close the protocol
+
+Arguments:
+
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+
+Returns:
+
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: NumberOfChildren - add argument and description to function comment
+// TODO: ChildHandleBuffer - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ DestroyRootBridgeByHandle (
+ Controller
+ );
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Stop all the children
+ //
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ //
+ // De register all the pci device
+ //
+ Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h new file mode 100644 index 0000000000..170a4e278a --- /dev/null +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h @@ -0,0 +1,243 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PciBus.h
+
+Abstract:
+
+ PCI Bus Driver
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PCI_BUS_H
+#define _EFI_PCI_BUS_H
+
+
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Acpi.h>
+#include "ComponentName.h"
+
+//
+// Driver Produced Protocol Prototypes
+//
+
+#define VGABASE1 0x3B0
+#define VGALIMIT1 0x3BB
+
+#define VGABASE2 0x3C0
+#define VGALIMIT2 0x3DF
+
+#define ISABASE 0x100
+#define ISALIMIT 0x3FF
+
+typedef enum {
+ PciBarTypeUnknown = 0,
+ PciBarTypeIo16,
+ PciBarTypeIo32,
+ PciBarTypeMem32,
+ PciBarTypePMem32,
+ PciBarTypeMem64,
+ PciBarTypePMem64,
+ PciBarTypeIo,
+ PciBarTypeMem,
+ PciBarTypeMaxType
+} PCI_BAR_TYPE;
+
+typedef struct {
+ UINT64 BaseAddress;
+ UINT64 Length;
+ UINT64 Alignment;
+ PCI_BAR_TYPE BarType;
+ BOOLEAN Prefetchable;
+ UINT8 MemType;
+ UINT8 Offset;
+} PCI_BAR;
+
+#define PPB_BAR_0 0
+#define PPB_BAR_1 1
+#define PPB_IO_RANGE 2
+#define PPB_MEM32_RANGE 3
+#define PPB_PMEM32_RANGE 4
+#define PPB_PMEM64_RANGE 5
+#define PPB_MEM64_RANGE 0xFF
+
+#define P2C_BAR_0 0
+#define P2C_MEM_1 1
+#define P2C_MEM_2 2
+#define P2C_IO_1 3
+#define P2C_IO_2 4
+
+#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'i', 'o')
+
+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001
+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002
+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004
+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008
+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010
+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020
+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040
+
+#define PCI_MAX_HOST_BRIDGE_NUM 0x0010
+//
+// Define resource status constant
+//
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL
+
+//
+// Define option for attribute
+//
+#define EFI_SET_SUPPORTS 0
+#define EFI_SET_ATTRIBUTES 1
+
+typedef struct _PCI_IO_DEVICE {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PROTOCOL PciIo;
+ LIST_ENTRY Link;
+
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+
+ //
+ // PCI configuration space header type
+ //
+ PCI_TYPE00 Pci;
+
+ //
+ // Bus number, Device number, Function number
+ //
+ UINT8 BusNumber;
+ UINT8 DeviceNumber;
+ UINT8 FunctionNumber;
+
+ //
+ // BAR for this PCI Device
+ //
+ PCI_BAR PciBar[PCI_MAX_BAR];
+
+ //
+ // The bridge device this pci device is subject to
+ //
+ struct _PCI_IO_DEVICE *Parent;
+
+ //
+ // A linked list for children Pci Device if it is bridge device
+ //
+ LIST_ENTRY ChildList;
+
+ //
+ // TURE if the PCI bus driver creates the handle for this PCI device
+ //
+ BOOLEAN Registered;
+
+ //
+ // TRUE if the PCI bus driver successfully allocates the resource required by
+ // this PCI device
+ //
+ BOOLEAN Allocated;
+
+ //
+ // The attribute this PCI device currently set
+ //
+ UINT64 Attributes;
+
+ //
+ // The attributes this PCI device actually supports
+ //
+ UINT64 Supports;
+
+ //
+ // The resource decode the bridge supports
+ //
+ UINT32 Decodes;
+
+ //
+ // The OptionRom Size
+ //
+ UINT64 RomSize;
+
+ //
+ // The OptionRom Size
+ //
+ UINT64 RomBase;
+
+ //
+ // TRUE if all OpROM (in device or in platform specific position) have been processed
+ //
+ BOOLEAN AllOpRomProcessed;
+
+ //
+ // TRUE if there is any EFI driver in the OptionRom
+ //
+ BOOLEAN BusOverride;
+
+ //
+ // A list tracking reserved resource on a bridge device
+ //
+ LIST_ENTRY ReservedResourceList;
+
+ //
+ // A list tracking image handle of platform specific overriding driver
+ //
+ LIST_ENTRY OptionRomDriverList;
+
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors;
+ EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;
+
+ BOOLEAN IsPciExp;
+
+} PCI_IO_DEVICE;
+
+
+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
+ CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \
+ CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_LINK(a) \
+ CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport;
+extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;
+extern LIST_ENTRY gPciDevicePool;
+extern BOOLEAN gFullEnumeration;
+extern UINTN gPciHostBridgeNumber;
+extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
+extern UINT64 gAllOne;
+extern UINT64 gAllZero;
+
+extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
+
+#include "PciIo.h"
+#include "PciCommand.h"
+#include "PciDeviceSupport.h"
+#include "PciEnumerator.h"
+#include "PciEnumeratorSupport.h"
+#include "PciDriverOverride.h"
+#include "PciRomTable.h"
+#include "PciOptionRomSupport.h"
+#include "PciPowerManagement.h"
+#include "PciHotPlugSupport.h"
+#include "PciLib.h"
+
+#endif
|