+/**\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%x;\tLength = 0x%x;\tAlignment = 0x%x\n",\r
+ mBarTypeStr[MIN (BridgeResource->ResType, PciBarTypeMaxType)],\r
+ BridgeResource->PciDev->PciBar[BridgeResource->Bar].BaseAddress,\r
+ BridgeResource->Length, BridgeResource->Alignment\r
+ ));\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->ResourceUsage == PciResUsageTypical) {\r
+ Bar = Resource->Virtual ? Resource->PciDev->VfPciBar : Resource->PciDev->PciBar;\r
+ DEBUG ((\r
+ EFI_D_INFO, " Base = 0x%x;\tLength = 0x%x;\tAlignment = 0x%x;\tOwner = %s ",\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
+ ));\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 ((\r
+ EFI_D_INFO, " [%02x|%02x|%02x:%02x]\n",\r
+ Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,\r
+ Resource->PciDev->FunctionNumber, Bar[Resource->Bar].Offset\r
+ ));\r
+ } else {\r
+ //\r
+ // The resource requirement comes from the subordinate devices.\r
+ //\r
+ DEBUG ((\r
+ EFI_D_INFO, " [%02x|%02x|%02x:**]\n",\r
+ Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,\r
+ Resource->PciDev->FunctionNumber\r
+ ));\r
+ }\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, " Padding:Length = 0x%x;\tAlignment = 0x%x\n", Resource->Length, Resource->Alignment));\r
+ }\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
+ \r
+ @return !NULL The corresponding resource node for the Device.\r
+ @return NULL No corresponding resource node for the Device.\r
+**/\r
+PCI_RESOURCE_NODE *\r
+FindResourceNode (\r
+ IN PCI_IO_DEVICE *Device,\r
+ IN PCI_RESOURCE_NODE *BridgeResource\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ PCI_RESOURCE_NODE *Resource;\r
+\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
+ return Resource;\r
+ }\r
+ }\r
+\r
+ return NULL;\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] IoNode IO resource descriptor for the bridge device.\r
+ @param[in] Mem32Node Mem32 resource descriptor for the bridge device.\r
+ @param[in] PMem32Node PMem32 resource descriptor for the bridge device.\r
+ @param[in] Mem64Node Mem64 resource descriptor for the bridge device.\r
+ @param[in] PMem64Node PMem64 resource descriptor for the bridge device.\r
+**/\r
+VOID\r
+DumpResourceMap (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ PCI_IO_DEVICE *Device;\r
+ PCI_RESOURCE_NODE *ChildIoNode;\r
+ PCI_RESOURCE_NODE *ChildMem32Node;\r
+ PCI_RESOURCE_NODE *ChildPMem32Node;\r
+ PCI_RESOURCE_NODE *ChildMem64Node;\r
+ PCI_RESOURCE_NODE *ChildPMem64Node;\r
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *ToText;\r
+ CHAR16 *Str;\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
+ Status = gBS->LocateProtocol (\r
+ &gEfiDevicePathToTextProtocolGuid,\r
+ NULL,\r
+ (VOID **) &ToText\r
+ );\r
+ Str = NULL;\r
+ if (!EFI_ERROR (Status)) {\r
+ Str = ToText->ConvertDevicePathToText (\r
+ DevicePathFromHandle (Bridge->Handle),\r
+ FALSE,\r
+ FALSE\r
+ );\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
+ DumpBridgeResource (IoNode);\r
+ DumpBridgeResource (Mem32Node);\r
+ DumpBridgeResource (PMem32Node);\r
+ DumpBridgeResource (Mem64Node);\r
+ DumpBridgeResource (PMem64Node);\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
+ ChildIoNode = (IoNode == NULL ? NULL : FindResourceNode (Device, IoNode));\r
+ ChildMem32Node = (Mem32Node == NULL ? NULL : FindResourceNode (Device, Mem32Node));\r
+ ChildPMem32Node = (PMem32Node == NULL ? NULL : FindResourceNode (Device, PMem32Node));\r
+ ChildMem64Node = (Mem64Node == NULL ? NULL : FindResourceNode (Device, Mem64Node));\r
+ ChildPMem64Node = (PMem64Node == NULL ? NULL : FindResourceNode (Device, PMem64Node));\r
+\r
+ DumpResourceMap (\r
+ Device,\r
+ ChildIoNode,\r
+ ChildMem32Node,\r
+ ChildPMem32Node,\r
+ ChildMem64Node,\r
+ ChildPMem64Node\r
+ );\r
+ }\r
+ }\r
+}\r
+\r