diff options
author | Laszlo Ersek <lersek@redhat.com> | 2015-07-14 12:02:29 +0000 |
---|---|---|
committer | lersek <lersek@Edk2> | 2015-07-14 12:02:29 +0000 |
commit | bdb1c98f036154b53d97cd5a30e49878e85fa8cb (patch) | |
tree | 71b4a63b525af9707beb010ce560d97312f483ab /OvmfPkg/PciHostBridgeDxe | |
parent | 83344cf60b7b212272aae365f9346c387873b059 (diff) | |
download | edk2-platforms-bdb1c98f036154b53d97cd5a30e49878e85fa8cb.tar.xz |
OvmfPkg: PciHostBridgeDxe: look for all root buses
In this patch we assume that root bus number 0 is always there (same as
before), and scan the rest of the extra root buses, up to and including
255. When an extra root bus is found, we install the PCI root bridge IO
protocol for the previous root bus (which might be bus 0 or just the
previous extra root bus).
The root bridge protocol created thus will report the available bus number
range
[own bus number, next extra root bus number - 1]
The LHS of this interval will be used for the root bus's own number, and
the rest of the interval (which might encompass 0 additional elements too)
can be used by the PCI bus driver to assign subordinate bus numbers from.
(Subordinate buses are provided by PCI bridges that hang off the root bus
in question.)
For MMIO and IO space allocation, all the root buses share the original
[0x8000_0000, 0xFFFF_FFFF] and [0x0, 0xFFFF] ranges, respectively.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17962 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/PciHostBridgeDxe')
-rw-r--r-- | OvmfPkg/PciHostBridgeDxe/PciHostBridge.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c index 7dda75f0d3..348664438d 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c @@ -43,14 +43,6 @@ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = { }
};
-//
-// Hard code: Root Bridge's resource aperture
-//
-
-PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture[1] = {
- {0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}
-};
-
EFI_HANDLE mDriverImageHandle;
PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
@@ -80,8 +72,15 @@ PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = { param[in] RootBusNumber The bus number of the root bus (root bridge) to
create.
- RootBusNumber is expected to fall into the valid
- offset range of mResAperture.
+
+ param[in] MaxSubBusNumber The inclusive maximum bus number that can be
+ assigned to any subordinate bus found behind any
+ PCI bridge hanging off this root bus.
+
+ The caller is repsonsible for ensuring that
+ RootBusNumber <= MaxSubBusNumber. If
+ RootBusNumber equals MaxSubBusNumber, then the
+ root bus has no room for subordinate buses.
param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host bridge
that is the parent of the root bridge to create.
@@ -108,12 +107,16 @@ STATIC EFI_STATUS
InitRootBridge (
IN UINT8 RootBusNumber,
+ IN UINT8 MaxSubBusNumber,
IN EFI_HANDLE HostBridgeHandle,
OUT PCI_ROOT_BRIDGE_INSTANCE **RootBus
)
{
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
- EFI_STATUS Status;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ PCI_ROOT_BRIDGE_RESOURCE_APERTURE ResAperture;
+ EFI_STATUS Status;
+
+ ASSERT (RootBusNumber <= MaxSubBusNumber);
PrivateData = AllocateZeroPool (sizeof *PrivateData);
if (PrivateData == NULL) {
@@ -126,13 +129,18 @@ InitRootBridge ( sizeof mRootBridgeDevicePathTemplate);
PrivateData->DevicePath.AcpiDevicePath.UID = RootBusNumber;
+ ResAperture.BusBase = RootBusNumber;
+ ResAperture.BusLimit = MaxSubBusNumber;
+ ResAperture.MemBase = BASE_2GB;
+ ResAperture.MemLimit = BASE_4GB - 1;
+ ResAperture.IoBase = 0;
+ ResAperture.IoLimit = MAX_UINT16;
//
// The function call below allocates no resources and performs no actions
// that have to be rolled back on later failure. It always succeeds.
//
Status = RootBridgeConstructor (&PrivateData->Io, HostBridgeHandle,
- EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM,
- &mResAperture[RootBusNumber]);
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, &ResAperture);
ASSERT_EFI_ERROR (Status);
Status = gBS->InstallMultipleProtocolInterfaces (&PrivateData->Handle,
@@ -143,6 +151,9 @@ InitRootBridge ( goto FreePrivateData;
}
+ DEBUG ((EFI_D_INFO,
+ "%a: installed root bus %d, with room for %d subordinate bus(es)\n",
+ __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
*RootBus = PrivateData;
return EFI_SUCCESS;
@@ -196,6 +207,7 @@ InitializePciHostBridge ( )
{
EFI_STATUS Status;
+ UINTN LastRootBridgeNumber;
UINTN RootBridgeNumber;
PCI_HOST_BRIDGE_INSTANCE *HostBridge;
PCI_ROOT_BRIDGE_INSTANCE *RootBus;
@@ -224,20 +236,55 @@ InitializePciHostBridge ( goto FreeHostBridge;
}
- for (RootBridgeNumber = 0;
- RootBridgeNumber < 1;
+ //
+ // The "main" root bus is always there.
+ //
+ LastRootBridgeNumber = 0;
+
+ //
+ // Scan all other root buses. If function 0 of any device on a bus returns a
+ // VendorId register value different from all-bits-one, then that bus is
+ // alive.
+ //
+ for (RootBridgeNumber = 1;
+ RootBridgeNumber < 256;
++RootBridgeNumber) {
- Status = InitRootBridge (
- (UINT8)RootBridgeNumber,
- HostBridge->HostBridgeHandle,
- &RootBus
- );
- if (EFI_ERROR (Status)) {
- goto RollbackProtocols;
+ UINTN Device;
+
+ for (Device = 0; Device <= MAX_PCI_DEVICE_NUMBER; ++Device) {
+ if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
+ PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
+ break;
+ }
+ }
+ if (Device <= MAX_PCI_DEVICE_NUMBER) {
+ //
+ // Found the next root bus. We can now install the *previous* one,
+ // because now we know how big a bus number range *that* one has, for any
+ // subordinate buses that might exist behind PCI bridges hanging off it.
+ //
+ Status = InitRootBridge ((UINT8)LastRootBridgeNumber,
+ (UINT8)(RootBridgeNumber - 1), HostBridge->HostBridgeHandle,
+ &RootBus);
+ if (EFI_ERROR (Status)) {
+ goto RollbackProtocols;
+ }
+ InsertTailList (&HostBridge->Head, &RootBus->Link);
+ LastRootBridgeNumber = RootBridgeNumber;
}
- InsertTailList (&HostBridge->Head, &RootBus->Link);
}
+ //
+ // Install the last root bus (which might be the only, ie. main, root bus, if
+ // we've found no extra root buses).
+ //
+ Status = InitRootBridge ((UINT8)LastRootBridgeNumber, 255,
+ HostBridge->HostBridgeHandle, &RootBus);
+ if (EFI_ERROR (Status)) {
+ goto RollbackProtocols;
+ }
+ InsertTailList (&HostBridge->Head, &RootBus->Link);
+
return EFI_SUCCESS;
RollbackProtocols:
|