}\r
};\r
\r
-//\r
-// Hard code: Root Bridge's resource aperture\r
-//\r
-\r
-PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture[1] = {\r
- {0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}\r
-};\r
-\r
EFI_HANDLE mDriverImageHandle;\r
\r
PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {\r
\r
param[in] RootBusNumber The bus number of the root bus (root bridge) to\r
create.\r
- RootBusNumber is expected to fall into the valid\r
- offset range of mResAperture.\r
+\r
+ param[in] MaxSubBusNumber The inclusive maximum bus number that can be\r
+ assigned to any subordinate bus found behind any\r
+ PCI bridge hanging off this root bus.\r
+\r
+ The caller is repsonsible for ensuring that\r
+ RootBusNumber <= MaxSubBusNumber. If\r
+ RootBusNumber equals MaxSubBusNumber, then the\r
+ root bus has no room for subordinate buses.\r
\r
param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host bridge\r
that is the parent of the root bridge to create.\r
EFI_STATUS\r
InitRootBridge (\r
IN UINT8 RootBusNumber,\r
+ IN UINT8 MaxSubBusNumber,\r
IN EFI_HANDLE HostBridgeHandle,\r
OUT PCI_ROOT_BRIDGE_INSTANCE **RootBus\r
)\r
{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
- EFI_STATUS Status;\r
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
+ PCI_ROOT_BRIDGE_RESOURCE_APERTURE ResAperture;\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (RootBusNumber <= MaxSubBusNumber);\r
\r
PrivateData = AllocateZeroPool (sizeof *PrivateData);\r
if (PrivateData == NULL) {\r
sizeof mRootBridgeDevicePathTemplate);\r
PrivateData->DevicePath.AcpiDevicePath.UID = RootBusNumber;\r
\r
+ ResAperture.BusBase = RootBusNumber;\r
+ ResAperture.BusLimit = MaxSubBusNumber;\r
+ ResAperture.MemBase = BASE_2GB;\r
+ ResAperture.MemLimit = BASE_4GB - 1;\r
+ ResAperture.IoBase = 0;\r
+ ResAperture.IoLimit = MAX_UINT16;\r
//\r
// The function call below allocates no resources and performs no actions\r
// that have to be rolled back on later failure. It always succeeds.\r
//\r
Status = RootBridgeConstructor (&PrivateData->Io, HostBridgeHandle,\r
- EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM,\r
- &mResAperture[RootBusNumber]);\r
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, &ResAperture);\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (&PrivateData->Handle,\r
goto FreePrivateData;\r
}\r
\r
+ DEBUG ((EFI_D_INFO,\r
+ "%a: installed root bus %d, with room for %d subordinate bus(es)\n",\r
+ __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));\r
*RootBus = PrivateData;\r
return EFI_SUCCESS;\r
\r
)\r
{\r
EFI_STATUS Status;\r
+ UINTN LastRootBridgeNumber;\r
UINTN RootBridgeNumber;\r
PCI_HOST_BRIDGE_INSTANCE *HostBridge;\r
PCI_ROOT_BRIDGE_INSTANCE *RootBus;\r
goto FreeHostBridge;\r
}\r
\r
- for (RootBridgeNumber = 0;\r
- RootBridgeNumber < 1;\r
+ //\r
+ // The "main" root bus is always there.\r
+ //\r
+ LastRootBridgeNumber = 0;\r
+\r
+ //\r
+ // Scan all other root buses. If function 0 of any device on a bus returns a\r
+ // VendorId register value different from all-bits-one, then that bus is\r
+ // alive.\r
+ //\r
+ for (RootBridgeNumber = 1;\r
+ RootBridgeNumber < 256;\r
++RootBridgeNumber) {\r
- Status = InitRootBridge (\r
- (UINT8)RootBridgeNumber,\r
- HostBridge->HostBridgeHandle,\r
- &RootBus\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto RollbackProtocols;\r
+ UINTN Device;\r
+\r
+ for (Device = 0; Device <= MAX_PCI_DEVICE_NUMBER; ++Device) {\r
+ if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,\r
+ PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {\r
+ break;\r
+ }\r
+ }\r
+ if (Device <= MAX_PCI_DEVICE_NUMBER) {\r
+ //\r
+ // Found the next root bus. We can now install the *previous* one,\r
+ // because now we know how big a bus number range *that* one has, for any\r
+ // subordinate buses that might exist behind PCI bridges hanging off it.\r
+ //\r
+ Status = InitRootBridge ((UINT8)LastRootBridgeNumber,\r
+ (UINT8)(RootBridgeNumber - 1), HostBridge->HostBridgeHandle,\r
+ &RootBus);\r
+ if (EFI_ERROR (Status)) {\r
+ goto RollbackProtocols;\r
+ }\r
+ InsertTailList (&HostBridge->Head, &RootBus->Link);\r
+ LastRootBridgeNumber = RootBridgeNumber;\r
}\r
- InsertTailList (&HostBridge->Head, &RootBus->Link);\r
}\r
\r
+ //\r
+ // Install the last root bus (which might be the only, ie. main, root bus, if\r
+ // we've found no extra root buses).\r
+ //\r
+ Status = InitRootBridge ((UINT8)LastRootBridgeNumber, 255,\r
+ HostBridge->HostBridgeHandle, &RootBus);\r
+ if (EFI_ERROR (Status)) {\r
+ goto RollbackProtocols;\r
+ }\r
+ InsertTailList (&HostBridge->Head, &RootBus->Link);\r
+\r
return EFI_SUCCESS;\r
\r
RollbackProtocols:\r