diff options
author | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-12-13 03:11:47 +0000 |
---|---|---|
committer | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-12-13 03:11:47 +0000 |
commit | 6874dbd0e24535c3c4a89dddfdac98ad25b0617b (patch) | |
tree | e3071114a459c2fce296316806ae09034e624cbf /EdkModulePkg/Bus/Pci | |
parent | bc022470e469566d807cf39b9e03cccc3b7e8685 (diff) | |
download | edk2-platforms-6874dbd0e24535c3c4a89dddfdac98ad25b0617b.tar.xz |
1) Use FeatureFlag PcdPciBusHotplugDeviceSupport to merge LightPciLib.c with PcdLib.c.
2) Correct some minor bugs: when invoking gRT->GetVariable the Attributes field can be optianal.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2090 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Bus/Pci')
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c | 6 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c | 3 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa | 26 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c | 697 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h | 36 |
5 files changed, 709 insertions, 59 deletions
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c index dfe134a2ee..75794f8125 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c @@ -161,7 +161,6 @@ IDEBusDriverConfigurationSetOptions ( UINT8 NewValue;
UINTN DataSize;
UINTN Index;
- UINT32 Attributes;
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
@@ -173,7 +172,7 @@ IDEBusDriverConfigurationSetOptions ( Status = gRT->GetVariable (
L"Configuration",
&gEfiCallerIdGuid,
- &Attributes,
+ NULL,
&DataSize,
&Value
);
@@ -255,7 +254,6 @@ IDEBusDriverConfigurationOptionsValid ( EFI_STATUS Status;
UINT8 Value;
UINTN DataSize;
- UINT32 Attributes;
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
@@ -265,7 +263,7 @@ IDEBusDriverConfigurationOptionsValid ( Status = gRT->GetVariable (
L"Configuration",
&gEfiCallerIdGuid,
- &Attributes,
+ NULL,
&DataSize,
&Value
);
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c index 83dd5510e4..d17ce5f07d 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c @@ -181,7 +181,6 @@ IDEBusDriverBindingStart ( UINT16 CommandBlockBaseAddr;
UINT16 ControlBlockBaseAddr;
UINTN DataSize;
- UINT32 Attributes;
IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
//
@@ -316,7 +315,7 @@ IDEBusDriverBindingStart ( Status = gRT->GetVariable (
(CHAR16 *) L"Configuration",
&gEfiCallerIdGuid,
- &Attributes,
+ NULL,
&DataSize,
&ConfigurationOptions
);
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa index 855fdd7591..b8e15f9fb3 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa @@ -6,18 +6,15 @@ <GuidValue>93B80004-9FB3-11d4-9A3A-0090273FC14D</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for PciBus module.</Abstract>
- <Description>PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO - space for these devices.
- LightPcdLib.c tagged with "ToolCode="DUMMY"" is light weight verison for PCI library
- function. This version provide simple implementation and do not support hot plug. Only one
- between PcdLib.c and LightPcdLib.c can be choosed.
- </Description>
+ <Description>PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO
+ space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable
+ support hot plug.</Description>
<Copyright>Copyright (c) 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, + <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>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
@@ -93,7 +90,6 @@ <Filename>pcibus.c</Filename>
<Filename>PciIo.c</Filename>
<Filename>PciLib.c</Filename>
- <Filename ToolCode="DUMMY">LightPciLib.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
@@ -178,5 +174,11 @@ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
<HelpText>Whether VGA decoding is enabled on this platform so we should avoid those aliased resources</HelpText>
</PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdPciBusHotplugDeviceSupport</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <DefaultValue>TRUE</DefaultValue>
+ <HelpText>If TRUE, the PCI bus driver will support hot plug device. If not hot plug device is supported, this feature flag can be set to FALSE to save size.</HelpText>
+ </PcdEntry>
</PcdCoded>
</ModuleSurfaceArea>
\ No newline at end of file diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c index 11a0c29210..a4d3577d35 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c @@ -25,7 +25,7 @@ Revision History #include "pcibus.h"
-EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {
PciHotPlugRequestNotify
};
@@ -49,6 +49,10 @@ Returns: {
EFI_HANDLE Handle;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return;
+ }
+
Handle = NULL;
*Status = gBS->InstallProtocolInterface (
&Handle,
@@ -78,6 +82,10 @@ Returns: {
EFI_STATUS Status;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return;
+ }
+
if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {
Status = gBS->InstallProtocolInterface (
@@ -109,6 +117,10 @@ Returns: {
EFI_STATUS Status;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return;
+ }
+
Status = gBS->OpenProtocol (
PciIoDevice->Handle,
&gEfiPciHotplugDeviceGuid,
@@ -152,6 +164,10 @@ Returns: {
UINT32 Address;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return;
+ }
+
//
// Read PciBar information from the bar register
//
@@ -239,6 +255,10 @@ Returns: LIST_ENTRY *CurrentLink;
LIST_ENTRY *LastLink;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return EFI_SUCCESS;
+ }
+
CurrentLink = Bridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &Bridge->ChildList) {
@@ -286,6 +306,396 @@ EFI_STATUS PciHostBridgeResourceAllocator (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
)
+{
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (
+ PciResAlloc
+ );
+ } else {
+ return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (
+ PciResAlloc
+ );
+ }
+}
+
+
+EFI_STATUS
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (
+ 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
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
/*++
Routine Description:
@@ -787,6 +1197,7 @@ Returns: return EFI_SUCCESS;
}
+
EFI_STATUS
PciScanBus (
IN PCI_IO_DEVICE *Bridge,
@@ -794,6 +1205,204 @@ PciScanBus ( OUT UINT8 *SubBusNumber,
OUT UINT8 *PaddedBusRange
)
+{
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return PciScanBus_WithHotPlugDeviceSupport (
+ Bridge,
+ StartBusNumber,
+ SubBusNumber,
+ PaddedBusRange
+ );
+ } else {
+ return PciScanBus_WithoutHotPlugDeviceSupport (
+ Bridge,
+ StartBusNumber,
+ SubBusNumber,
+ PaddedBusRange
+ );
+ }
+}
+
+
+EFI_STATUS
+PciScanBus_WithoutHotPlugDeviceSupport (
+ 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;
+}
+
+EFI_STATUS
+PciScanBus_WithHotPlugDeviceSupport (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
/*++
Routine Description:
@@ -1175,6 +1784,10 @@ Returns: PCI_IO_DEVICE *RootBridgeDev;
EFI_STATUS Status;
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ return EFI_SUCCESS;
+ }
+
RootBridgeHandle = NULL;
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
@@ -1271,55 +1884,63 @@ Returns: //
}
- //
- // 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 (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
+ //
+ // Notify the bus allocation phase is finished for the first time
+ //
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
+
+
+ if (gPciHotPlugInit != NULL) {
//
- // if a root bridge instance is found, create root bridge device for it
+ // Wait for all HPC initialized
//
+ Status = AllRootHPCInitialized (STALL_1_SECOND * 15);
- RootBridgeDev = CreateRootBridge (RootBridgeHandle);
-
- if (RootBridgeDev == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ if (EFI_ERROR (Status)) {
+ return Status;
}
//
- // Enumerate all the buses under this root bridge
+ // 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) {
- Status = PciRootBridgeEnumerator (
- PciResAlloc,
- RootBridgeDev
- );
+ //
+ // if a root bridge instance is found, create root bridge device for it
+ //
- DestroyRootBridge (RootBridgeDev);
- if (EFI_ERROR (Status)) {
- return Status;
+ 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);
}
-
+ } else {
//
// Notify the bus allocation phase is to end
//
diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h index 1e89445df6..f8e88375d7 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h @@ -15,9 +15,9 @@ Module Name: 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
+ PCI Bus Driver Lib header file.
+ Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable
+ support hot plug.
Revision History
@@ -155,6 +155,18 @@ Returns: ;
EFI_STATUS
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+;
+
+EFI_STATUS
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
+ )
+;
+
+EFI_STATUS
PciScanBus (
IN PCI_IO_DEVICE *Bridge,
IN UINT8 StartBusNumber,
@@ -182,6 +194,24 @@ Returns: ;
EFI_STATUS
+PciScanBus_WithHotPlugDeviceSupport (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
+;
+
+EFI_STATUS
+PciScanBus_WithoutHotPlugDeviceSupport (
+ IN PCI_IO_DEVICE *Bridge,
+ IN UINT8 StartBusNumber,
+ OUT UINT8 *SubBusNumber,
+ OUT UINT8 *PaddedBusRange
+ )
+;
+
+EFI_STATUS
PciRootBridgeP2CProcess (
IN PCI_IO_DEVICE *Bridge
)
|