X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FPciBusDxe%2FPciResourceSupport.c;h=70e45040e2efb2777f3386c59f0a620e06302d91;hp=2cacd441c8830f40c82711f36f143bde87f6c25c;hb=0fa92d5839cddeb63a7e4583fdbca49b16599e3a;hpb=9060e3ec6dfd6048724832947933650cde873381 diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c index 2cacd441c8..70e45040e2 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c @@ -1,8 +1,8 @@ /** @file - PCI resouces support functions implemntation for PCI Bus module. + PCI resources support functions implementation for PCI Bus module. -Copyright (c) 2006 - 2009, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+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 http://opensource.org/licenses/bsd-license.php @@ -14,6 +14,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "PciBus.h" +// +// The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases. +// +BOOLEAN mReserveIsaAliases = FALSE; +BOOLEAN mReserveVgaAliases = FALSE; +BOOLEAN mPolicyDetermined = FALSE; + /** The function is used to skip VGA range. @@ -127,11 +134,11 @@ InsertResourceNode ( /** This routine is used to merge two different resource trees in need of - resoure degradation. + resource degradation. For example, if an upstream PPB doesn't support, prefetchable memory decoding, the PCI bus driver will choose to call this function - to merge prefectchable memory resource list into normal memory list. + to merge prefetchable memory resource list into normal memory list. If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource type. @@ -188,63 +195,61 @@ CalculateApertureIo16 ( LIST_ENTRY *CurrentLink; PCI_RESOURCE_NODE *Node; UINT64 Offset; - BOOLEAN IsaEnable; - BOOLEAN VGAEnable; EFI_PCI_PLATFORM_POLICY PciPolicy; + UINT64 PaddingAperture; - // - // Always assume there is ISA device and VGA device on the platform - // will be customized later - // - IsaEnable = FALSE; - VGAEnable = FALSE; + if (!mPolicyDetermined) { + // + // Check PciPlatform policy + // + Status = EFI_NOT_FOUND; + PciPolicy = 0; + if (gPciPlatformProtocol != NULL) { + Status = gPciPlatformProtocol->GetPlatformPolicy ( + gPciPlatformProtocol, + &PciPolicy + ); + } - // - // Check PciPlatform policy - // - if (gPciPlatformProtocol != NULL) { - Status = gPciPlatformProtocol->GetPlatformPolicy ( - gPciPlatformProtocol, - &PciPolicy - ); - if (!EFI_ERROR (Status)) { - if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) { - IsaEnable = TRUE; - } - if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) { - VGAEnable = TRUE; - } + if (EFI_ERROR (Status) && gPciOverrideProtocol != NULL) { + Status = gPciOverrideProtocol->GetPlatformPolicy ( + gPciOverrideProtocol, + &PciPolicy + ); } - } else if (gPciOverrideProtocol != NULL) { - Status = gPciOverrideProtocol->GetPlatformPolicy ( - gPciOverrideProtocol, - &PciPolicy - ); + if (!EFI_ERROR (Status)) { if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) { - IsaEnable = TRUE; + mReserveIsaAliases = TRUE; } if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) { - VGAEnable = TRUE; + mReserveVgaAliases = TRUE; } } + mPolicyDetermined = TRUE; } - Aperture = 0; + Aperture = 0; + PaddingAperture = 0; if (Bridge == NULL) { return ; } - CurrentLink = Bridge->ChildList.ForwardLink; - // // Assume the bridge is aligned // - while (CurrentLink != &Bridge->ChildList) { + for ( CurrentLink = GetFirstNode (&Bridge->ChildList) + ; !IsNull (&Bridge->ChildList, CurrentLink) + ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink) + ) { Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - + if (Node->ResourceUsage == PciResUsagePadding) { + ASSERT (PaddingAperture == 0); + PaddingAperture = Node->Length; + continue; + } // // Consider the aperture alignment // @@ -261,13 +266,13 @@ CalculateApertureIo16 ( // If both of them are enabled, then the IO resource would // become too limited to meet the requirement of most of devices. // - if (IsaEnable || VGAEnable) { + if (mReserveIsaAliases || mReserveVgaAliases) { if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { // // Check if there is need to support ISA/VGA decoding // If so, we need to avoid isa/vga aliasing range // - if (IsaEnable) { + if (mReserveIsaAliases) { SkipIsaAliasAperture ( &Aperture, Node->Length @@ -276,7 +281,7 @@ CalculateApertureIo16 ( if (Offset != 0) { Aperture = Aperture + (Node->Alignment + 1) - Offset; } - } else if (VGAEnable) { + } else if (mReserveVgaAliases) { SkipVGAAperture ( &Aperture, Node->Length @@ -295,13 +300,10 @@ CalculateApertureIo16 ( // Increment aperture by the length of node // Aperture += Node->Length; - - CurrentLink = CurrentLink->ForwardLink; } // - // At last, adjust the aperture with the bridge's - // alignment + // Adjust the aperture with the bridge's alignment // Offset = Aperture & (Bridge->Alignment); @@ -321,13 +323,19 @@ CalculateApertureIo16 ( Bridge->Alignment = Node->Alignment; } } + + // + // Hotplug controller needs padding resources. + // Use the larger one between the padding resource and actual occupied resource. + // + Bridge->Length = MAX (Bridge->Length, PaddingAperture); } /** This function is used to calculate the resource aperture for a given bridge device. - @param Bridge PCI resouce node for given bridge device. + @param Bridge PCI resource node for given bridge device. **/ VOID @@ -335,14 +343,10 @@ CalculateResourceAperture ( IN PCI_RESOURCE_NODE *Bridge ) { - UINT64 Aperture; + UINT64 Aperture[2]; LIST_ENTRY *CurrentLink; PCI_RESOURCE_NODE *Node; - UINT64 Offset; - - Aperture = 0; - if (Bridge == NULL) { return ; } @@ -353,64 +357,51 @@ CalculateResourceAperture ( return ; } - CurrentLink = Bridge->ChildList.ForwardLink; - + Aperture[PciResUsageTypical] = 0; + Aperture[PciResUsagePadding] = 0; // // Assume the bridge is aligned // - while (CurrentLink != &Bridge->ChildList) { - + for ( CurrentLink = GetFirstNode (&Bridge->ChildList) + ; !IsNull (&Bridge->ChildList, CurrentLink) + ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink) + ) { Node = RESOURCE_NODE_FROM_LINK (CurrentLink); // - // Apply padding resource if available + // It's possible for a bridge to contain multiple padding resource + // nodes due to DegradeResource(). // - Offset = Aperture & (Node->Alignment); - - if (Offset != 0) { - - Aperture = Aperture + (Node->Alignment + 1) - Offset; - - } - + ASSERT ((Node->ResourceUsage == PciResUsageTypical) || + (Node->ResourceUsage == PciResUsagePadding)); + ASSERT (Node->ResourceUsage < ARRAY_SIZE (Aperture)); // // Recode current aperture as a offset - // this offset will be used in future real allocation + // Apply padding resource to meet alignment requirement + // Node offset will be used in future real allocation // - Node->Offset = Aperture; + Node->Offset = ALIGN_VALUE (Aperture[Node->ResourceUsage], Node->Alignment + 1); // - // Increment aperture by the length of node + // Record the total aperture. // - Aperture += Node->Length; - - // - // Consider the aperture alignment - // - CurrentLink = CurrentLink->ForwardLink; + Aperture[Node->ResourceUsage] = Node->Offset + Node->Length; } // - // At last, adjust the aperture with the bridge's - // alignment + // Adjust the aperture with the bridge's alignment // - Offset = Aperture & (Bridge->Alignment); - if (Offset != 0) { - Aperture = Aperture + (Bridge->Alignment + 1) - Offset; - } + Aperture[PciResUsageTypical] = ALIGN_VALUE (Aperture[PciResUsageTypical], Bridge->Alignment + 1); + Aperture[PciResUsagePadding] = ALIGN_VALUE (Aperture[PciResUsagePadding], Bridge->Alignment + 1); // - // If the bridge has already padded the resource and the - // amount of padded resource is larger, then keep the - // padded resource + // Hotplug controller needs padding resources. + // Use the larger one between the padding resource and actual occupied resource. // - if (Bridge->Length < Aperture) { - Bridge->Length = Aperture; - } + Bridge->Length = MAX (Aperture[PciResUsageTypical], Aperture[PciResUsagePadding]); // - // At last, adjust the bridge's alignment to the first child's alignment - // if the bridge has at least one child + // Adjust the bridge's alignment to the MAX (first) alignment of all children. // CurrentLink = Bridge->ChildList.ForwardLink; if (CurrentLink != &Bridge->ChildList) { @@ -422,7 +413,7 @@ CalculateResourceAperture ( } /** - Get IO/Memory resource infor for given PCI device. + Get IO/Memory resource info for given PCI device. @param PciDev Pci device instance. @param IoNode Resource info node for IO . @@ -455,13 +446,14 @@ GetResourceFromDevice ( switch ((PciDev->PciBar)[Index].BarType) { case PciBarTypeMem32: + case PciBarTypeOpRom: Node = CreateResourceNode ( PciDev, (PciDev->PciBar)[Index].Length, (PciDev->PciBar)[Index].Alignment, Index, - PciBarTypeMem32, + (PciDev->PciBar)[Index].BarType, PciResUsageTypical ); @@ -726,17 +718,6 @@ CreateVfResourceNode ( { PCI_RESOURCE_NODE *Node; - DEBUG (( - EFI_D_INFO, - "PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n", - (UINTN)PciDev->BusNumber, - (UINTN)PciDev->DeviceNumber, - (UINTN)PciDev->FunctionNumber, - (UINTN)Bar, - (UINTN)ResType, - (UINTN)Length - )); - Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage); if (Node == NULL) { return Node; @@ -803,14 +784,12 @@ CreateResourceMap ( // // If the device has children, create a bridge resource node for this PPB // Note: For PPB, memory aperture is aligned with 1MB and IO aperture - // is aligned with 4KB - // This device is typically a bridge device like PPB and P2C - // Note: 0x1000 aligned + // is aligned with 4KB (smaller alignments may be supported). // IoBridge = CreateResourceNode ( Temp, 0, - 0xFFF, + Temp->BridgeIoAlignment, PPB_IO_RANGE, PciBarTypeIo16, PciResUsageTypical @@ -853,7 +832,7 @@ CreateResourceMap ( ); // - // Recursively create resouce map on this bridge + // Recursively create resource map on this bridge // CreateResourceMap ( Temp, @@ -1049,31 +1028,69 @@ DegradeResource ( IN PCI_RESOURCE_NODE *PMem64Node ) { - BOOLEAN HasOprom; - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *PciIoDevice; + LIST_ENTRY *ChildDeviceLink; + LIST_ENTRY *ChildNodeLink; + LIST_ENTRY *NextChildNodeLink; + PCI_RESOURCE_NODE *ResourceNode; - // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // to find if this bridge and downstream has OptionRom. - // - HasOprom = FALSE; - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { + if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom)) { + // + // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64 + // requests in case that if a legacy option ROM image can not access 64-bit resources. + // + ChildDeviceLink = Bridge->ChildList.ForwardLink; + while (ChildDeviceLink != NULL && ChildDeviceLink != &Bridge->ChildList) { + PciIoDevice = PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink); + if (PciIoDevice->RomSize != 0) { + if (!IsListEmpty (&Mem64Node->ChildList)) { + ChildNodeLink = Mem64Node->ChildList.ForwardLink; + while (ChildNodeLink != &Mem64Node->ChildList) { + ResourceNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink); + NextChildNodeLink = ChildNodeLink->ForwardLink; + + if ((ResourceNode->PciDev == PciIoDevice) && + (ResourceNode->Virtual || !PciIoDevice->PciBar[ResourceNode->Bar].BarTypeFixed) + ) { + RemoveEntryList (ChildNodeLink); + InsertResourceNode (Mem32Node, ResourceNode); + } + ChildNodeLink = NextChildNodeLink; + } + } - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (Temp->RomSize != 0) { - HasOprom = TRUE; - break; + if (!IsListEmpty (&PMem64Node->ChildList)) { + ChildNodeLink = PMem64Node->ChildList.ForwardLink; + while (ChildNodeLink != &PMem64Node->ChildList) { + ResourceNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink); + NextChildNodeLink = ChildNodeLink->ForwardLink; + + if ((ResourceNode->PciDev == PciIoDevice) && + (ResourceNode->Virtual || !PciIoDevice->PciBar[ResourceNode->Bar].BarTypeFixed) + ) { + RemoveEntryList (ChildNodeLink); + InsertResourceNode (PMem32Node, ResourceNode); + } + ChildNodeLink = NextChildNodeLink; + } + } + + } + ChildDeviceLink = ChildDeviceLink->ForwardLink; } - CurrentLink = CurrentLink->ForwardLink; } // - // If bridge doesn't support Prefetchable - // memory64, degrade it to Prefetchable memory32 + // If firmware is in 32-bit mode, + // then degrade PMEM64/MEM64 requests // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { + if (sizeof (UINTN) <= 4) { + MergeResourceTree ( + Mem32Node, + Mem64Node, + TRUE + ); + MergeResourceTree ( PMem32Node, PMem64Node, @@ -1081,31 +1098,38 @@ DegradeResource ( ); } else { // - // if no PMem32 request and no OptionRom request, still keep PMem64. Otherwise degrade to PMem32 + // if the bridge does not support MEM64, degrade MEM64 to MEM32 // - if ((PMem32Node != NULL && (PMem32Node->Length != 0 && Bridge->Parent != NULL)) || HasOprom) { - // - // Fixed the issue that there is no resource for 64-bit (above 4G) - // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { + MergeResourceTree ( + Mem32Node, + Mem64Node, + TRUE + ); + } + + // + // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32 + // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { MergeResourceTree ( PMem32Node, PMem64Node, TRUE ); } - } - - // - // If bridge doesn't support Mem64 - // degrade it to mem32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - Mem64Node, - TRUE - ); + // + // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied + // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32. + // + if (!IsListEmpty (&PMem64Node->ChildList) && Bridge->Parent != NULL) { + MergeResourceTree ( + Mem32Node, + PMem32Node, + TRUE + ); + } } // @@ -1121,7 +1145,7 @@ DegradeResource ( } // - // if bridge supports combined Pmem Mem decoding + // if root bridge supports combined Pmem Mem decoding // merge these two type of resource // if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { @@ -1131,6 +1155,11 @@ DegradeResource ( FALSE ); + // + // No need to check if to degrade MEM64 after merge, because + // if there are PMEM64 still here, 64-bit decode should be supported + // by the root bride. + // MergeResourceTree ( Mem64Node, PMem64Node, @@ -1166,10 +1195,10 @@ BridgeSupportResourceDecode ( This function is used to program the resource allocated for each resource node under specified bridge. - @param Base Base address of resource to be progammed. + @param Base Base address of resource to be programmed. @param Bridge PCI resource node for the bridge device. - @retval EFI_SUCCESS Successfully to program all resouces + @retval EFI_SUCCESS Successfully to program all resources on given PCI bridge device. @retval EFI_OUT_OF_RESOURCES Base is all one. @@ -1228,8 +1257,8 @@ ProgramResource ( /** Program Bar register for PCI device. - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. + @param Base Base address for PCI device resource to be programmed. + @param Node Point to resource node structure. **/ VOID @@ -1249,6 +1278,7 @@ ProgramBar ( // if (Node->Virtual) { ProgramVfBar (Base, Node); + return; } Address = 0; @@ -1278,7 +1308,13 @@ ProgramBar ( 1, &Address ); + // + // Continue to the case PciBarTypeOpRom to set the BaseAddress. + // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture + // the MEM32 resource requirement for Option ROM shadow. + // + case PciBarTypeOpRom: Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; break; @@ -1318,8 +1354,8 @@ ProgramBar ( /** Program IOV VF Bar register for PCI device. - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. + @param Base Base address for PCI device resource to be programmed. + @param Node Point to resource node structure. **/ EFI_STATUS @@ -1362,17 +1398,6 @@ ProgramVfBar ( ); Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address; - - DEBUG (( - EFI_D_INFO, - "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n", - (UINTN)Node->PciDev->BusNumber, - (UINTN)Node->PciDev->DeviceNumber, - (UINTN)Node->PciDev->FunctionNumber, - (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset, - (UINTN)Address - )); - break; case PciBarTypeMem64: @@ -1399,17 +1424,6 @@ ProgramVfBar ( ); Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address; - - DEBUG (( - EFI_D_INFO, - "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n", - (UINTN)Node->PciDev->BusNumber, - (UINTN)Node->PciDev->DeviceNumber, - (UINTN)Node->PciDev->FunctionNumber, - (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset, - (UINT64)Address - )); - break; case PciBarTypeIo16: @@ -1424,10 +1438,10 @@ ProgramVfBar ( } /** - Program PCI-PCI bridge apperture. + Program PCI-PCI bridge aperture. @param Base Base address for resource. - @param Node Point to resoure node structure. + @param Node Point to resource node structure. **/ VOID @@ -1443,7 +1457,7 @@ ProgramPpbApperture ( Address = 0; // // If no device resource of this PPB, return anyway - // Apperture is set default in the initialization code + // Aperture is set default in the initialization code // if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) { // @@ -1464,7 +1478,14 @@ ProgramPpbApperture ( case PPB_BAR_0: case PPB_BAR_1: - PciIo->Pci.Write ( + switch ((Node->PciDev->PciBar[Node->Bar]).BarType) { + + case PciBarTypeIo16: + case PciBarTypeIo32: + case PciBarTypeMem32: + case PciBarTypePMem32: + + PciIo->Pci.Write ( PciIo, EfiPciIoWidthUint32, (Node->PciDev->PciBar[Node->Bar]).Offset, @@ -1472,9 +1493,40 @@ ProgramPpbApperture ( &Address ); - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + + case PciBarTypeMem64: + case PciBarTypePMem64: + + Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); + + PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint32, + (Node->PciDev->PciBar[Node->Bar]).Offset, + 1, + &Address32 + ); + + Address32 = (UINT32) RShiftU64 (Address, 32); + + PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint32, + (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4), + 1, + &Address32 + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + default: + break; + } break; case PPB_IO_RANGE: @@ -1597,45 +1649,64 @@ ProgramPpbApperture ( /** Program parent bridge for Option Rom. - @param PciDevice Pci deivce instance. - @param OptionRomBase Base address for Optiona Rom. + @param PciDevice Pci device instance. + @param OptionRomBase Base address for Option Rom. @param Enable Enable or disable PCI memory. **/ VOID -ProgrameUpstreamBridgeForRom ( +ProgramUpstreamBridgeForRom ( IN PCI_IO_DEVICE *PciDevice, IN UINT32 OptionRomBase, IN BOOLEAN Enable ) { - PCI_IO_DEVICE *Parent; - PCI_RESOURCE_NODE Node; + PCI_IO_DEVICE *Parent; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT16 Base; + UINT16 Limit; // // For root bridge, just return. // Parent = PciDevice->Parent; - ZeroMem (&Node, sizeof (Node)); while (Parent != NULL) { if (!IS_PCI_BRIDGE (&Parent->Pci)) { break; } - Node.PciDev = Parent; - Node.Length = PciDevice->RomSize; - Node.Alignment = 0; - Node.Bar = PPB_MEM32_RANGE; - Node.ResType = PciBarTypeMem32; - Node.Offset = 0; + PciIo = &Parent->PciIo; // - // Program PPB to only open a single <= 16MB apperture + // Program PPB to only open a single <= 16MB aperture // if (Enable) { - ProgramPpbApperture (OptionRomBase, &Node); + // + // Only cover MMIO for Option ROM. + // + Base = (UINT16) (OptionRomBase >> 16); + Limit = (UINT16) ((OptionRomBase + PciDevice->RomSize - 1) >> 16); + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), 1, &Base); + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit); + PCI_ENABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE); } else { - InitializePpb (Parent); + // + // Cover 32bit MMIO for devices below the bridge. + // + if (Parent->PciBar[PPB_MEM32_RANGE].Length == 0) { + // + // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO. + // + Base = (UINT16) gAllOne; + Limit = (UINT16) gAllZero; + } else { + Base = (UINT16) ((UINT32) Parent->PciBar[PPB_MEM32_RANGE].BaseAddress >> 16); + Limit = (UINT16) ((UINT32) (Parent->PciBar[PPB_MEM32_RANGE].BaseAddress + + Parent->PciBar[PPB_MEM32_RANGE].Length - 1) >> 16); + } + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), 1, &Base); + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit); + PCI_DISABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE); } @@ -1686,125 +1757,8 @@ InitializeResourcePool ( InitializeListHead (&ResourcePool->ChildList); } - -/** - Get all resource information for given Pci device. - - @param PciDev Pci device instance. - @param IoBridge Io resource node. - @param Mem32Bridge 32-bit memory node. - @param PMem32Bridge 32-bit Pmemory node. - @param Mem64Bridge 64-bit memory node. - @param PMem64Bridge 64-bit PMemory node. - @param IoPool Link list header for Io resource. - @param Mem32Pool Link list header for 32-bit memory. - @param PMem32Pool Link list header for 32-bit Prefetchable memory. - @param Mem64Pool Link list header for 64-bit memory. - @param PMem64Pool Link list header for 64-bit Prefetchable memory. - -**/ -VOID -GetResourceMap ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE **IoBridge, - IN PCI_RESOURCE_NODE **Mem32Bridge, - IN PCI_RESOURCE_NODE **PMem32Bridge, - IN PCI_RESOURCE_NODE **Mem64Bridge, - IN PCI_RESOURCE_NODE **PMem64Bridge, - IN PCI_RESOURCE_NODE *IoPool, - IN PCI_RESOURCE_NODE *Mem32Pool, - IN PCI_RESOURCE_NODE *PMem32Pool, - IN PCI_RESOURCE_NODE *Mem64Pool, - IN PCI_RESOURCE_NODE *PMem64Pool - ) -{ - - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - - CurrentLink = IoPool->ChildList.ForwardLink; - - // - // Get Io resource map - // - while (CurrentLink != &IoPool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *IoBridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Mem32 resource map - // - CurrentLink = Mem32Pool->ChildList.ForwardLink; - - while (CurrentLink != &Mem32Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *Mem32Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Pmem32 resource map - // - CurrentLink = PMem32Pool->ChildList.ForwardLink; - - while (CurrentLink != &PMem32Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *PMem32Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Mem64 resource map - // - CurrentLink = Mem64Pool->ChildList.ForwardLink; - - while (CurrentLink != &Mem64Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *Mem64Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Pmem64 resource map - // - CurrentLink = PMem64Pool->ChildList.ForwardLink; - - while (CurrentLink != &PMem64Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *PMem64Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } -} - /** - Destory given resource tree. + Destroy given resource tree. @param Bridge PCI resource root node of resource tree. @@ -1861,7 +1815,7 @@ ResourcePaddingForCardBusBridge ( // // Memory Base/Limit Register 0 - // Bar 1 denodes memory range 0 + // Bar 1 decodes memory range 0 // Node = CreateResourceNode ( PciDev, @@ -1879,7 +1833,7 @@ ResourcePaddingForCardBusBridge ( // // Memory Base/Limit Register 1 - // Bar 2 denodes memory range1 + // Bar 2 decodes memory range1 // Node = CreateResourceNode ( PciDev, @@ -1897,7 +1851,7 @@ ResourcePaddingForCardBusBridge ( // // Io Base/Limit - // Bar 3 denodes io range 0 + // Bar 3 decodes io range 0 // Node = CreateResourceNode ( PciDev, @@ -1915,7 +1869,7 @@ ResourcePaddingForCardBusBridge ( // // Io Base/Limit - // Bar 4 denodes io range 0 + // Bar 4 decodes io range 0 // Node = CreateResourceNode ( PciDev, @@ -2019,7 +1973,7 @@ ProgramP2C ( } else { // - // Set pre-fetchable bit + // Set prefetchable bit // PciIo->Pci.Read ( PciIo, @@ -2089,7 +2043,7 @@ ProgramP2C ( } else { // - // Set pre-fetchable bit + // Set prefetchable bit // PciIo->Pci.Read ( PciIo, @@ -2222,7 +2176,7 @@ ApplyResourcePadding ( if (Ptr->AddrSpaceGranularity == 32) { // - // prefechable + // prefetchable // if (Ptr->SpecificFlag == 0x6) { if (Ptr->AddrLen != 0) { @@ -2245,7 +2199,7 @@ ApplyResourcePadding ( } // - // Non-prefechable + // Non-prefetchable // if (Ptr->SpecificFlag == 0) { if (Ptr->AddrLen != 0) { @@ -2271,7 +2225,7 @@ ApplyResourcePadding ( if (Ptr->AddrSpaceGranularity == 64) { // - // prefechable + // prefetchable // if (Ptr->SpecificFlag == 0x6) { if (Ptr->AddrLen != 0) { @@ -2294,7 +2248,7 @@ ApplyResourcePadding ( } // - // Non-prefechable + // Non-prefetchable // if (Ptr->SpecificFlag == 0) { if (Ptr->AddrLen != 0) {