+/**\r
+ Dump the resourc map of the bridge device.\r
+\r
+ @param[in] BridgeResource Resource descriptor of the bridge device.\r
+**/\r
+VOID\r
+DumpBridgeResource (\r
+ IN PCI_RESOURCE_NODE *BridgeResource\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ PCI_RESOURCE_NODE *Resource;\r
+ PCI_BAR *Bar;\r
+\r
+ if ((BridgeResource != NULL) && (BridgeResource->Length != 0)) {\r
+ DEBUG ((\r
+ EFI_D_INFO, "Type = %s; Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx\n",\r
+ mBarTypeStr[MIN (BridgeResource->ResType, PciBarTypeMaxType)],\r
+ BridgeResource->PciDev->PciBar[BridgeResource->Bar].BaseAddress,\r
+ BridgeResource->Length, BridgeResource->Alignment\r
+ ));\r
+ for ( Link = GetFirstNode (&BridgeResource->ChildList)\r
+ ; !IsNull (&BridgeResource->ChildList, Link)\r
+ ; Link = GetNextNode (&BridgeResource->ChildList, Link)\r
+ ) {\r
+ Resource = RESOURCE_NODE_FROM_LINK (Link);\r
+ if (Resource->ResourceUsage == PciResUsageTypical) {\r
+ Bar = Resource->Virtual ? Resource->PciDev->VfPciBar : Resource->PciDev->PciBar;\r
+ DEBUG ((\r
+ EFI_D_INFO, " Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx;\tOwner = %s [%02x|%02x|%02x:",\r
+ Bar[Resource->Bar].BaseAddress, Resource->Length, Resource->Alignment,\r
+ IS_PCI_BRIDGE (&Resource->PciDev->Pci) ? L"PPB" :\r
+ IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci) ? L"P2C" :\r
+ L"PCI",\r
+ Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,\r
+ Resource->PciDev->FunctionNumber\r
+ ));\r
+\r
+ if ((!IS_PCI_BRIDGE (&Resource->PciDev->Pci) && !IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci)) ||\r
+ (IS_PCI_BRIDGE (&Resource->PciDev->Pci) && (Resource->Bar < PPB_IO_RANGE)) ||\r
+ (IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci) && (Resource->Bar < P2C_MEM_1))\r
+ ) {\r
+ //\r
+ // The resource requirement comes from the device itself.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "%02x]", Bar[Resource->Bar].Offset));\r
+ } else {\r
+ //\r
+ // The resource requirement comes from the subordinate devices.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "**]"));\r
+ }\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, " Base = Padding;\tLength = 0x%lx;\tAlignment = 0x%lx", Resource->Length, Resource->Alignment));\r
+ }\r
+ if (BridgeResource->ResType != Resource->ResType) {\r
+ DEBUG ((EFI_D_INFO, "; Type = %s", mBarTypeStr[MIN (Resource->ResType, PciBarTypeMaxType)]));\r
+ }\r
+ DEBUG ((EFI_D_INFO, "\n"));\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Find the corresponding resource node for the Device in child list of BridgeResource.\r
+\r
+ @param[in] Device Pointer to PCI_IO_DEVICE.\r
+ @param[in] BridgeResource Pointer to PCI_RESOURCE_NODE.\r
+ @param[out] DeviceResources Pointer to a buffer to receive resources for the Device.\r
+\r
+ @return Count of the resource descriptors returned.\r
+**/\r
+UINTN\r
+FindResourceNode (\r
+ IN PCI_IO_DEVICE *Device,\r
+ IN PCI_RESOURCE_NODE *BridgeResource,\r
+ OUT PCI_RESOURCE_NODE **DeviceResources OPTIONAL\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ PCI_RESOURCE_NODE *Resource;\r
+ UINTN Count;\r
+\r
+ Count = 0;\r
+ for ( Link = BridgeResource->ChildList.ForwardLink\r
+ ; Link != &BridgeResource->ChildList\r
+ ; Link = Link->ForwardLink\r
+ ) {\r
+ Resource = RESOURCE_NODE_FROM_LINK (Link);\r
+ if (Resource->PciDev == Device) {\r
+ if (DeviceResources != NULL) {\r
+ DeviceResources[Count] = Resource;\r
+ }\r
+ Count++;\r
+ }\r
+ }\r
+\r
+ return Count;\r
+}\r
+\r
+/**\r
+ Dump the resource map of all the devices under Bridge.\r
+\r
+ @param[in] Bridge Bridge device instance.\r
+ @param[in] Resources Resource descriptors for the bridge device.\r
+ @param[in] ResourceCount Count of resource descriptors.\r
+**/\r
+VOID\r
+DumpResourceMap (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE **Resources,\r
+ IN UINTN ResourceCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ PCI_IO_DEVICE *Device;\r
+ UINTN Index;\r
+ CHAR16 *Str;\r
+ PCI_RESOURCE_NODE **ChildResources;\r
+ UINTN ChildResourceCount;\r
+\r
+ DEBUG ((EFI_D_INFO, "PciBus: Resource Map for "));\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Bridge->Handle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ EFI_D_INFO, "Bridge [%02x|%02x|%02x]\n",\r
+ Bridge->BusNumber, Bridge->DeviceNumber, Bridge->FunctionNumber\r
+ ));\r
+ } else {\r
+ Str = ConvertDevicePathToText (\r
+ DevicePathFromHandle (Bridge->Handle),\r
+ FALSE,\r
+ FALSE\r
+ );\r
+ DEBUG ((EFI_D_INFO, "Root Bridge %s\n", Str != NULL ? Str : L""));\r
+ if (Str != NULL) {\r
+ FreePool (Str);\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < ResourceCount; Index++) {\r
+ DumpBridgeResource (Resources[Index]);\r
+ }\r
+ DEBUG ((EFI_D_INFO, "\n"));\r
+\r
+ for ( Link = Bridge->ChildList.ForwardLink\r
+ ; Link != &Bridge->ChildList\r
+ ; Link = Link->ForwardLink\r
+ ) {\r
+ Device = PCI_IO_DEVICE_FROM_LINK (Link);\r
+ if (IS_PCI_BRIDGE (&Device->Pci)) {\r
+\r
+ ChildResourceCount = 0;\r
+ for (Index = 0; Index < ResourceCount; Index++) {\r
+ ChildResourceCount += FindResourceNode (Device, Resources[Index], NULL);\r
+ }\r
+ ChildResources = AllocatePool (sizeof (PCI_RESOURCE_NODE *) * ChildResourceCount);\r
+ ASSERT (ChildResources != NULL);\r
+ ChildResourceCount = 0;\r
+ for (Index = 0; Index < ResourceCount; Index++) {\r
+ ChildResourceCount += FindResourceNode (Device, Resources[Index], &ChildResources[ChildResourceCount]);\r
+ }\r
+\r
+ DumpResourceMap (Device, ChildResources, ChildResourceCount);\r
+ FreePool (ChildResources);\r
+ }\r
+ }\r
+}\r
+\r