mirror of https://github.com/acidanthera/audk.git
MdeModulePkg PciBusDxe: The PCI Bus Driver is updated to support multiple PCI bus ranges for a PCI root bridge.
Signed-off-by: rsun3 Reviewed-by: vanjeff git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12600 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2d3fb91987
commit
306bbe82cb
|
@ -268,6 +268,11 @@ struct _PCI_IO_DEVICE {
|
|||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors;
|
||||
EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;
|
||||
|
||||
//
|
||||
// Bus number ranges for a PCI Root Bridge device
|
||||
//
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BusNumberRanges;
|
||||
|
||||
BOOLEAN IsPciExp;
|
||||
//
|
||||
// For SR-IOV
|
||||
|
|
|
@ -158,10 +158,16 @@ PciRootBridgeEnumerator (
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration1;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration2;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration3;
|
||||
UINT8 SubBusNumber;
|
||||
UINT8 StartBusNumber;
|
||||
UINT8 PaddedBusRange;
|
||||
EFI_HANDLE RootBridgeHandle;
|
||||
UINT8 Desc;
|
||||
UINT64 AddrLen;
|
||||
UINT64 AddrRangeMin;
|
||||
|
||||
SubBusNumber = 0;
|
||||
StartBusNumber = 0;
|
||||
|
@ -191,11 +197,40 @@ PciRootBridgeEnumerator (
|
|||
return Status;
|
||||
}
|
||||
|
||||
if (Configuration == NULL || Configuration->Desc == ACPI_END_TAG_DESCRIPTOR) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
RootBridgeDev->BusNumberRanges = Configuration;
|
||||
|
||||
//
|
||||
// Sort the descriptors in ascending order
|
||||
//
|
||||
for (Configuration1 = Configuration; Configuration1->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration1++) {
|
||||
Configuration2 = Configuration1;
|
||||
for (Configuration3 = Configuration1 + 1; Configuration3->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration3++) {
|
||||
if (Configuration2->AddrRangeMin > Configuration3->AddrRangeMin) {
|
||||
Configuration2 = Configuration3;
|
||||
}
|
||||
}
|
||||
//
|
||||
// All other fields other than AddrRangeMin and AddrLen are ignored in a descriptor,
|
||||
// so only need to swap these two fields.
|
||||
//
|
||||
if (Configuration2 != Configuration1) {
|
||||
AddrRangeMin = Configuration1->AddrRangeMin;
|
||||
Configuration1->AddrRangeMin = Configuration2->AddrRangeMin;
|
||||
Configuration2->AddrRangeMin = AddrRangeMin;
|
||||
|
||||
AddrLen = Configuration1->AddrLen;
|
||||
Configuration1->AddrLen = Configuration2->AddrLen;
|
||||
Configuration2->AddrLen = AddrLen;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get the bus number to start with
|
||||
//
|
||||
StartBusNumber = (UINT8) (Configuration->AddrRangeMin);
|
||||
PaddedBusRange = (UINT8) (Configuration->AddrRangeMax);
|
||||
|
||||
//
|
||||
// Initialize the subordinate bus number
|
||||
|
@ -215,7 +250,7 @@ PciRootBridgeEnumerator (
|
|||
//
|
||||
Status = PciScanBus (
|
||||
RootBridgeDev,
|
||||
(UINT8) (Configuration->AddrRangeMin),
|
||||
StartBusNumber,
|
||||
&SubBusNumber,
|
||||
&PaddedBusRange
|
||||
);
|
||||
|
@ -228,24 +263,45 @@ PciRootBridgeEnumerator (
|
|||
//
|
||||
// Assign max bus number scanned
|
||||
//
|
||||
Configuration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;
|
||||
|
||||
Status = PciAllocateBusNumber (RootBridgeDev, SubBusNumber, PaddedBusRange, &SubBusNumber);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Find the bus range which contains the higest bus number, then returns the number of buses
|
||||
// that should be decoded.
|
||||
//
|
||||
while (Configuration->AddrRangeMin + Configuration->AddrLen - 1 < SubBusNumber) {
|
||||
Configuration++;
|
||||
}
|
||||
AddrLen = Configuration->AddrLen;
|
||||
Configuration->AddrLen = SubBusNumber - Configuration->AddrRangeMin + 1;
|
||||
|
||||
//
|
||||
// Save the Desc field of the next descriptor. Mark the next descriptor as an END descriptor.
|
||||
//
|
||||
Configuration++;
|
||||
Desc = Configuration->Desc;
|
||||
Configuration->Desc = ACPI_END_TAG_DESCRIPTOR;
|
||||
|
||||
//
|
||||
// Set bus number
|
||||
//
|
||||
Status = PciResAlloc->SetBusNumbers (
|
||||
PciResAlloc,
|
||||
RootBridgeHandle,
|
||||
Configuration
|
||||
RootBridgeDev->BusNumberRanges
|
||||
);
|
||||
|
||||
FreePool (Configuration);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
//
|
||||
// Restore changed fields
|
||||
//
|
||||
Configuration->Desc = Desc;
|
||||
(Configuration - 1)->AddrLen = AddrLen;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,7 +407,11 @@ PciAssignBusNumber (
|
|||
//
|
||||
// Reserved one bus for cardbus bridge
|
||||
//
|
||||
SecondBus = ++(*SubBusNumber);
|
||||
Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
SecondBus = *SubBusNumber;
|
||||
|
||||
Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
|
||||
|
||||
|
|
|
@ -896,6 +896,64 @@ PciHostBridgeResourceAllocator (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocate NumberOfBuses buses and return the next available PCI bus number.
|
||||
|
||||
@param Bridge Bridge device instance.
|
||||
@param StartBusNumber Current available PCI bus number.
|
||||
@param NumberOfBuses Number of buses enumerated below the StartBusNumber.
|
||||
@param NextBusNumber Next available PCI bus number.
|
||||
|
||||
@retval EFI_SUCCESS Available bus number resource is enough. Next available PCI bus number
|
||||
is returned in NextBusNumber.
|
||||
@retval EFI_OUT_OF_RESOURCES Available bus number resource is not enough for allocation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PciAllocateBusNumber (
|
||||
IN PCI_IO_DEVICE *Bridge,
|
||||
IN UINT8 StartBusNumber,
|
||||
IN UINT8 NumberOfBuses,
|
||||
OUT UINT8 *NextBusNumber
|
||||
)
|
||||
{
|
||||
PCI_IO_DEVICE *RootBridge;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BusNumberRanges;
|
||||
UINT8 NextNumber;
|
||||
UINT64 MaxNumberInRange;
|
||||
|
||||
//
|
||||
// Get PCI Root Bridge device
|
||||
//
|
||||
RootBridge = Bridge;
|
||||
while (RootBridge->Parent != NULL) {
|
||||
RootBridge = RootBridge->Parent;
|
||||
}
|
||||
|
||||
//
|
||||
// Get next available PCI bus number
|
||||
//
|
||||
BusNumberRanges = RootBridge->BusNumberRanges;
|
||||
while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) {
|
||||
MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;
|
||||
if (StartBusNumber >= BusNumberRanges->AddrRangeMin && StartBusNumber <= MaxNumberInRange) {
|
||||
NextNumber = StartBusNumber + NumberOfBuses;
|
||||
while (NextNumber > MaxNumberInRange) {
|
||||
++BusNumberRanges;
|
||||
if (BusNumberRanges->Desc == ACPI_END_TAG_DESCRIPTOR) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
NextNumber += (UINT8)(BusNumberRanges->AddrRangeMin - (MaxNumberInRange + 1));
|
||||
MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;
|
||||
}
|
||||
*NextBusNumber = NextNumber;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
BusNumberRanges++;
|
||||
}
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/**
|
||||
Scan pci bus and assign bus number to the given PCI bus system.
|
||||
|
||||
|
@ -1100,15 +1158,10 @@ PciScanBus (
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add feature to support customized secondary bus number
|
||||
//
|
||||
if (*SubBusNumber == 0) {
|
||||
*SubBusNumber = *PaddedBusRange;
|
||||
*PaddedBusRange = 0;
|
||||
Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
(*SubBusNumber)++;
|
||||
SecondBus = *SubBusNumber;
|
||||
|
||||
Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
|
||||
|
@ -1173,7 +1226,10 @@ PciScanBus (
|
|||
(State & EFI_HPC_STATE_INITIALIZED) != 0) {
|
||||
*PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);
|
||||
} else {
|
||||
*SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);
|
||||
Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (BusRange), SubBusNumber);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1253,10 @@ PciScanBus (
|
|||
if (PcdGetBool (PcdSrIovSupport) && PciDevice->SrIovCapabilityOffset != 0) {
|
||||
if (TempReservedBusNum < PciDevice->ReservedBusNum) {
|
||||
|
||||
(*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);
|
||||
Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (PciDevice->ReservedBusNum - TempReservedBusNum), SubBusNumber);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
TempReservedBusNum = PciDevice->ReservedBusNum;
|
||||
|
||||
if (Func == 0) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Internal library declaration for PCI Bus module.
|
||||
|
||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -74,6 +74,27 @@ PciHostBridgeResourceAllocator (
|
|||
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
|
||||
);
|
||||
|
||||
/**
|
||||
Allocate NumberOfBuses buses and return the next available PCI bus number.
|
||||
|
||||
@param Bridge Bridge device instance.
|
||||
@param StartBusNumber Current available PCI bus number.
|
||||
@param NumberOfBuses Number of buses enumerated below the StartBusNumber.
|
||||
@param NextBusNumber Next available PCI bus number.
|
||||
|
||||
@retval EFI_SUCCESS Available bus number resource is enough. Next available PCI bus number
|
||||
is returned in NextBusNumber.
|
||||
@retval EFI_OUT_OF_RESOURCES Available bus number resource is not enough for allocation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PciAllocateBusNumber (
|
||||
IN PCI_IO_DEVICE *Bridge,
|
||||
IN UINT8 StartBusNumber,
|
||||
IN UINT8 NumberOfBuses,
|
||||
OUT UINT8 *NextBusNumber
|
||||
);
|
||||
|
||||
/**
|
||||
Scan pci bus and assign bus number to the given PCI bus system.
|
||||
|
||||
|
|
Loading…
Reference in New Issue