+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciResourceSupport.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciResourceSupport.h"\r
-#include "PciCommand.h"\r
-\r
-EFI_STATUS\r
-SkipVGAAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- The function is used to skip VGA range\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Start - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Original;\r
- UINT64 Mask;\r
- UINT64 StartOffset;\r
- UINT64 LimitOffset;\r
-\r
- //\r
- // For legacy VGA, bit 10 to bit 15 is not decoded\r
- //\r
- Mask = 0x3FF;\r
-\r
- Original = *Start;\r
- StartOffset = Original & Mask;\r
- LimitOffset = ((*Start) + Length - 1) & Mask;\r
- if (LimitOffset >= VGABASE1) {\r
- *Start = *Start - StartOffset + VGALIMIT2 + 1;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SkipIsaAliasAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to skip ISA aliasing aperture\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Start - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT64 Original;\r
- UINT64 Mask;\r
- UINT64 StartOffset;\r
- UINT64 LimitOffset;\r
-\r
- //\r
- // For legacy ISA, bit 10 to bit 15 is not decoded\r
- //\r
- Mask = 0x3FF;\r
-\r
- Original = *Start;\r
- StartOffset = Original & Mask;\r
- LimitOffset = ((*Start) + Length - 1) & Mask;\r
-\r
- if (LimitOffset >= ISABASE) {\r
- *Start = *Start - StartOffset + ISALIMIT + 1;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InsertResourceNode (\r
- PCI_RESOURCE_NODE *Bridge,\r
- PCI_RESOURCE_NODE *ResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function inserts a resource node into the resource list.\r
- The resource list is sorted in descend order.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: ResNode - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Temp;\r
- UINT64 ResNodeAlignRest;\r
- UINT64 TempAlignRest;\r
-\r
- InsertHeadList (&Bridge->ChildList, &ResNode->Link);\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;\r
- while (CurrentLink != &Bridge->ChildList) {\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (ResNode->Alignment > Temp->Alignment) {\r
- break;\r
- } else if (ResNode->Alignment == Temp->Alignment) {\r
- ResNodeAlignRest = ResNode->Length & ResNode->Alignment;\r
- TempAlignRest = Temp->Length & Temp->Alignment;\r
- if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {\r
- break;\r
- }\r
- }\r
-\r
- SwapListEntries (&ResNode->Link, CurrentLink);\r
-\r
- CurrentLink = ResNode->Link.ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-MergeResourceTree (\r
- PCI_RESOURCE_NODE *Dst,\r
- PCI_RESOURCE_NODE *Res,\r
- BOOLEAN TypeMerge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to merge two different resource tree in need of\r
- resoure degradation. For example, if a upstream PPB doesn't support,\r
- prefetchable memory decoding, the PCI bus driver will choose to call this function\r
- to merge prefectchable memory resource list into normal memory list.\r
-\r
- If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource\r
- type.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Dst - add argument and description to function comment\r
-// TODO: Res - add argument and description to function comment\r
-// TODO: TypeMerge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Temp;\r
-\r
- while (!IsListEmpty (&Res->ChildList)) {\r
- CurrentLink = Res->ChildList.ForwardLink;\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (TypeMerge) {\r
- Temp->ResType = Dst->ResType;\r
- }\r
-\r
- RemoveEntryList (CurrentLink);\r
- InsertResourceNode (Dst, Temp);\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CalculateApertureIo16 (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to calculate the IO16 aperture\r
- for a bridge.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT64 Aperture;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
- UINT64 offset;\r
- BOOLEAN IsaEnable;\r
- BOOLEAN VGAEnable;\r
-\r
- //\r
- // Always assume there is ISA device and VGA device on the platform\r
- // will be customized later\r
- //\r
- IsaEnable = FALSE;\r
- VGAEnable = FALSE;\r
-\r
- if (FeaturePcdGet (PcdPciIsaEnable)){\r
- IsaEnable = TRUE;\r
- }\r
-\r
- if (FeaturePcdGet (PcdPciVgaEnable)){\r
- VGAEnable = TRUE;\r
- }\r
-\r
- Aperture = 0;\r
-\r
- if (!Bridge) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- //\r
- // Assume the bridge is aligned\r
- //\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Consider the aperture alignment\r
- //\r
- offset = Aperture & (Node->Alignment);\r
-\r
- if (offset) {\r
-\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
-\r
- }\r
-\r
- //\r
- // IsaEnable and VGAEnable can not be implemented now.\r
- // If both of them are enabled, then the IO resource would\r
- // become too limited to meet the requirement of most of devices.\r
- //\r
-\r
- if (IsaEnable || VGAEnable) {\r
- if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
- //\r
- // Check if there is need to support ISA/VGA decoding\r
- // If so, we need to avoid isa/vga aliasing range\r
- //\r
- if (IsaEnable) {\r
- SkipIsaAliasAperture (\r
- &Aperture,\r
- Node->Length \r
- );\r
- offset = Aperture & (Node->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
- }\r
- } else if (VGAEnable) {\r
- SkipVGAAperture (\r
- &Aperture,\r
- Node->Length\r
- );\r
- offset = Aperture & (Node->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
- }\r
- }\r
- }\r
- }\r
-\r
- Node->Offset = Aperture;\r
-\r
- //\r
- // Increment aperture by the length of node\r
- //\r
- Aperture += Node->Length;\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // At last, adjust the aperture with the bridge's\r
- // alignment\r
- //\r
- offset = Aperture & (Bridge->Alignment);\r
-\r
- if (offset) {\r
- Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
- }\r
-\r
- Bridge->Length = Aperture;\r
- //\r
- // At last, adjust the bridge's alignment to the first child's alignment\r
- // if the bridge has at least one child\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- if (CurrentLink != &Bridge->ChildList) {\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
- if (Node->Alignment > Bridge->Alignment) {\r
- Bridge->Alignment = Node->Alignment;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CalculateResourceAperture (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to calculate the resource aperture\r
- for a given bridge device\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Aperture;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- UINT64 offset;\r
-\r
- Aperture = 0;\r
-\r
- if (!Bridge) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Bridge->ResType == PciBarTypeIo16) {\r
- return CalculateApertureIo16 (Bridge);\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- //\r
- // Assume the bridge is aligned\r
- //\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Apply padding resource if available\r
- //\r
- \r
- offset = Aperture & (Node->Alignment);\r
-\r
- if (offset) {\r
-\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
-\r
- }\r
-\r
- //\r
- // Recode current aperture as a offset\r
- // this offset will be used in future real allocation\r
- //\r
- Node->Offset = Aperture;\r
-\r
- //\r
- // Increment aperture by the length of node\r
- //\r
- Aperture += Node->Length;\r
-\r
- //\r
- // Consider the aperture alignment\r
- //\r
- \r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // At last, adjust the aperture with the bridge's\r
- // alignment\r
- //\r
- offset = Aperture & (Bridge->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
- }\r
-\r
- //\r
- // If the bridge has already padded the resource and the\r
- // amount of padded resource is larger, then keep the\r
- // padded resource\r
- //\r
- if (Bridge->Length < Aperture) {\r
- Bridge->Length = Aperture;\r
- }\r
- \r
- //\r
- // At last, adjust the bridge's alignment to the first child's alignment\r
- // if the bridge has at least one child\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- if (CurrentLink != &Bridge->ChildList) {\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
- if (Node->Alignment > Bridge->Alignment) {\r
- Bridge->Alignment = Node->Alignment;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceFromDevice (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT8 Index;\r
- PCI_RESOURCE_NODE *Node;\r
- BOOLEAN ResourceRequested;\r
-\r
- Node = NULL;\r
- ResourceRequested = FALSE;\r
-\r
- for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
-\r
- switch ((PciDev->PciBar)[Index].BarType) {\r
-\r
- case PciBarTypeMem32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeMem64:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- Mem64Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypePMem64:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- PMem64Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypePMem32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeIo16:\r
- case PciBarTypeIo32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeUnknown:\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // If there is no resource requested from this device,\r
- // then we indicate this device has been allocated naturally.\r
- //\r
- if (!ResourceRequested) {\r
- PciDev->Allocated = TRUE;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-CreateResourceNode (\r
- IN PCI_IO_DEVICE *PciDev,\r
- IN UINT64 Length,\r
- IN UINT64 Alignment,\r
- IN UINT8 Bar,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_RESOURCE_USAGE ResUsage\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to create a resource node\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: Alignment - add argument and description to function comment\r
-// TODO: Bar - add argument and description to function comment\r
-// TODO: ResType - add argument and description to function comment\r
-// TODO: ResUsage - add argument and description to function comment\r
-{\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- Node = NULL;\r
-\r
- Node = AllocatePool (sizeof (PCI_RESOURCE_NODE));\r
- if (Node == NULL) {\r
- return NULL;\r
- }\r
-\r
- ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));\r
-\r
- Node->Signature = PCI_RESOURCE_SIGNATURE;\r
- Node->PciDev = PciDev;\r
- Node->Length = Length;\r
- Node->Alignment = Alignment;\r
- Node->Bar = Bar;\r
- Node->ResType = ResType;\r
- Node->Reserved = FALSE;\r
- Node->ResourceUsage = ResUsage;\r
- InitializeListHead (&Node->ChildList);\r
- return Node;\r
-}\r
-\r
-EFI_STATUS\r
-CreateResourceMap (\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
-\r
-Routine Description:\r
-\r
- This routine is used to extract resource request from\r
- device node list.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Create resource nodes for this device by scanning the\r
- // Bar array in the device private data\r
- // If the upstream bridge doesn't support this device,\r
- // no any resource node will be created for this device\r
- //\r
- GetResourceFromDevice (\r
- Temp,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
-\r
- //\r
- // If the device has children, create a bridge resource node for this PPB\r
- // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
- // is aligned with 4KB\r
- // This device is typically a bridge device like PPB and P2C\r
- //\r
- IoBridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFF,\r
- PPB_IO_RANGE,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- ); //0x1000 aligned\r
- \r
- Mem32Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_MEM32_RANGE,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_PMEM32_RANGE,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_MEM64_RANGE,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_PMEM64_RANGE,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Recursively create resouce map on this bridge\r
- //\r
- CreateResourceMap (\r
- Temp,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- if (ResourceRequestExisted (IoBridge)) {\r
- InsertResourceNode (\r
- IoNode,\r
- IoBridge\r
- );\r
- } else {\r
- gBS->FreePool (IoBridge);\r
- IoBridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (Mem32Bridge)) {\r
- InsertResourceNode (\r
- Mem32Node,\r
- Mem32Bridge\r
- );\r
- } else {\r
- gBS->FreePool (Mem32Bridge);\r
- Mem32Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (PMem32Bridge)) {\r
- InsertResourceNode (\r
- PMem32Node,\r
- PMem32Bridge\r
- );\r
- } else {\r
- gBS->FreePool (PMem32Bridge);\r
- PMem32Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (Mem64Bridge)) {\r
- InsertResourceNode (\r
- Mem64Node,\r
- Mem64Bridge\r
- );\r
- } else {\r
- gBS->FreePool (Mem64Bridge);\r
- Mem64Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (PMem64Bridge)) {\r
- InsertResourceNode (\r
- PMem64Node,\r
- PMem64Bridge\r
- );\r
- } else {\r
- gBS->FreePool (PMem64Bridge);\r
- PMem64Bridge = NULL;\r
- }\r
-\r
- }\r
-\r
- //\r
- // If it is P2C, apply hard coded resource padding\r
- //\r
- //\r
- if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
- ResourcePaddingForCardBusBridge (\r
- Temp,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- //\r
- //\r
- // To do some platform specific resource padding ...\r
- //\r
- ResourcePaddingPolicy (\r
- Bridge,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- //\r
- // Degrade resource if necessary\r
- //\r
- DegradeResource (\r
- Bridge,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- //\r
- // Calculate resource aperture for this bridge device\r
- //\r
- CalculateResourceAperture (Mem32Node);\r
- CalculateResourceAperture (PMem32Node);\r
- CalculateResourceAperture (Mem64Node);\r
- CalculateResourceAperture (PMem64Node);\r
- CalculateResourceAperture (IoNode);\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-ResourcePaddingPolicy (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to do the resource padding for a specific platform\r
-\r
-Arguments:\r
-\r
- PciDev - A pointer to the PCI_IO_DEVICE structrue. \r
- IoNode - A pointer to the PCI_RESOURCE_NODE structrue.\r
- Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
-\r
-Returns:\r
- Status code\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- //\r
- // Create padding resource node\r
- //\r
- if (PciDev->ResourcePaddingDescriptors != NULL) {\r
- ApplyResourcePadding (\r
- PciDev,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-DegradeResource (\r
- IN PCI_IO_DEVICE *Bridge,\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
-\r
-Routine Description:\r
-\r
- This function is used to degrade resource if the upstream bridge \r
- doesn't support certain resource. Degradation path is \r
- PMEM64 -> MEM64 -> MEM32\r
- PMEM64 -> PMEM32 -> MEM32\r
- IO32 -> IO16\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- //\r
- // If bridge doesn't support Prefetchable\r
- // memory64, degrade it to Prefetchable memory32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- PMem32Node,\r
- PMem64Node,\r
- TRUE\r
- );\r
- } else {\r
- //\r
- // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32\r
- //\r
- if (PMem32Node != NULL) {\r
- MergeResourceTree (\r
- PMem32Node,\r
- PMem64Node,\r
- TRUE\r
- );\r
- }\r
- }\r
-\r
-\r
- //\r
- // If bridge doesn't support Mem64\r
- // degrade it to mem32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- Mem64Node,\r
- TRUE\r
- );\r
- }\r
-\r
- //\r
- // If bridge doesn't support Pmem32\r
- // degrade it to mem32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- PMem32Node,\r
- TRUE\r
- );\r
- }\r
-\r
- //\r
- // if bridge supports combined Pmem Mem decoding\r
- // merge these two type of resource\r
- //\r
- if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- PMem32Node,\r
- FALSE\r
- );\r
-\r
- MergeResourceTree (\r
- Mem64Node,\r
- PMem64Node,\r
- FALSE\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-BridgeSupportResourceDecode (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT32 Decode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Decode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
- /*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
- if ((Bridge->Decodes) & Decode) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramResource (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to program the resource allocated \r
- for each resource node\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
- EFI_STATUS Status;\r
-\r
- if (Base == gAllOne) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {\r
-\r
- if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
- ProgramP2C (Base, Node);\r
- } else {\r
- ProgramBar (Base, Node);\r
- }\r
- } else {\r
- Status = ProgramResource (Base + Node->Offset, Node);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- ProgramPpbApperture (Base, Node);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramBar (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT32 Address32;\r
-\r
- Address = 0;\r
- PciIo = &(Node->PciDev->PciIo);\r
-\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate pci bus driver has allocated\r
- // resource for this device\r
- // It might be a temporary solution here since\r
- // pci device could have multiple bar\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {\r
-\r
- case PciBarTypeIo16:\r
- case PciBarTypeIo32:\r
- case PciBarTypeMem32:\r
- case PciBarTypePMem32:\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
-\r
- break;\r
-\r
- case PciBarTypeMem64:\r
- case PciBarTypePMem64:\r
-\r
- Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 (Address, 32);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
-\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramPpbApperture (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT32 Address32;\r
-\r
- Address = 0;\r
- //\r
- // if no device south of this PPB, return anyway\r
- // Apperture is set default in the initialization code\r
- //\r
- if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {\r
- //\r
- // For padding resource node, just ignore when programming\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- PciIo = &(Node->PciDev->PciIo);\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate the PPB resource has been allocated\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch (Node->Bar) {\r
-\r
- case PPB_BAR_0:\r
- case PPB_BAR_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
-\r
- break;\r
-\r
- case PPB_IO_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x1C,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 >>= 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x30,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x1D,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 >>= 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x32,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case PPB_MEM32_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x20,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x22,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case PPB_PMEM32_RANGE:\r
- case PPB_PMEM64_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x24,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x26,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 (Address, 32);\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x28,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x2C,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgrameUpstreamBridgeForRom (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT32 OptionRomBase,\r
- IN BOOLEAN Enable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: OptionRomBase - add argument and description to function comment\r
-// TODO: Enable - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Parent;\r
- PCI_RESOURCE_NODE Node;\r
- //\r
- // For root bridge, just return.\r
- //\r
- Parent = PciDevice->Parent;\r
- ZeroMem (&Node, sizeof (Node));\r
- while (Parent) {\r
- if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
- break;\r
- }\r
-\r
- Node.PciDev = Parent;\r
- Node.Length = PciDevice->RomSize;\r
- Node.Alignment = 0;\r
- Node.Bar = PPB_MEM32_RANGE;\r
- Node.ResType = PciBarTypeMem32;\r
- Node.Offset = 0;\r
-\r
- //\r
- // Program PPB to only open a single <= 16<MB apperture\r
- //\r
- if (Enable) {\r
- ProgramPpbApperture (OptionRomBase, &Node);\r
- PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
- } else {\r
- InitializePpb (Parent);\r
- PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
- }\r
-\r
- Parent = Parent->Parent;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-ResourceRequestExisted (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_RESOURCE_NODE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- if (Bridge != NULL) {\r
- if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-InitializeResourcePool (\r
- PCI_RESOURCE_NODE *ResourcePool,\r
- PCI_BAR_TYPE ResourceType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: ResourcePool - add argument and description to function comment\r
-// TODO: ResourceType - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));\r
- ResourcePool->ResType = ResourceType;\r
- ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;\r
- InitializeListHead (&ResourcePool->ChildList);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceMap (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE **IoBridge,\r
- PCI_RESOURCE_NODE **Mem32Bridge,\r
- PCI_RESOURCE_NODE **PMem32Bridge,\r
- PCI_RESOURCE_NODE **Mem64Bridge,\r
- PCI_RESOURCE_NODE **PMem64Bridge,\r
- PCI_RESOURCE_NODE *IoPool,\r
- PCI_RESOURCE_NODE *Mem32Pool,\r
- PCI_RESOURCE_NODE *PMem32Pool,\r
- PCI_RESOURCE_NODE *Mem64Pool,\r
- PCI_RESOURCE_NODE *PMem64Pool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoBridge - add argument and description to function comment\r
-// TODO: Mem32Bridge - add argument and description to function comment\r
-// TODO: PMem32Bridge - add argument and description to function comment\r
-// TODO: Mem64Bridge - add argument and description to function comment\r
-// TODO: PMem64Bridge - add argument and description to function comment\r
-// TODO: IoPool - add argument and description to function comment\r
-// TODO: Mem32Pool - add argument and description to function comment\r
-// TODO: PMem32Pool - add argument and description to function comment\r
-// TODO: Mem64Pool - add argument and description to function comment\r
-// TODO: PMem64Pool - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = IoPool->ChildList.ForwardLink;\r
-\r
- //\r
- // Get Io resource map\r
- //\r
- while (CurrentLink != &IoPool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *IoBridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Mem32 resource map\r
- //\r
- CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Mem32Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *Mem32Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Pmem32 resource map\r
- //\r
- CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &PMem32Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *PMem32Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Mem64 resource map\r
- //\r
- CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Mem64Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *Mem64Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Pmem64 resource map\r
- //\r
- CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &PMem64Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *PMem64Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyResourceTree (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- while (!IsListEmpty (&Bridge->ChildList)) {\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- RemoveEntryList (CurrentLink);\r
-\r
- if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {\r
- DestroyResourceTree (Temp);\r
- }\r
-\r
- gBS->FreePool (Temp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RecordReservedResource (\r
- IN UINT64 Base,\r
- IN UINT64 Length,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: ResType - add argument and description to function comment\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESERVED_RESOURCE_LIST *ReservedNode;\r
-\r
- ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));\r
- if (ReservedNode == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;\r
- ReservedNode->Node.Base = Base;\r
- ReservedNode->Node.Length = Length;\r
- ReservedNode->Node.ResType = ResType;\r
-\r
- InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ResourcePaddingForCardBusBridge (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- Node = NULL;\r
-\r
- //\r
- // Memory Base/Limit Register 0\r
- // Bar 1 denodes memory range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x2000000,\r
- 0x1ffffff,\r
- 1,\r
- PciBarTypeMem32,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
-\r
- //\r
- // Memory Base/Limit Register 1\r
- // Bar 2 denodes memory range1\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x2000000,\r
- 0x1ffffff,\r
- 2,\r
- PciBarTypePMem32,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
-\r
- //\r
- // Io Base/Limit\r
- // Bar 3 denodes io range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x100,\r
- 0xff,\r
- 3,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
-\r
- //\r
- // Io Base/Limit\r
- // Bar 4 denodes io range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x100,\r
- 0xff,\r
- 4,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramP2C (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT64 TempAddress;\r
- UINT16 BridgeControl;\r
-\r
- Address = 0;\r
- PciIo = &(Node->PciDev->PciIo);\r
-\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate pci bus driver has allocated\r
- // resource for this device\r
- // It might be a temporary solution here since\r
- // pci device could have multiple bar\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch (Node->Bar) {\r
-\r
- case P2C_BAR_0:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case P2C_MEM_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x1c,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x20,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- if (Node->ResType == PciBarTypeMem32) {\r
-\r
- //\r
- // Set non-prefetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl &= 0xfeff;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- } else {\r
-\r
- //\r
- // Set pre-fetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl |= 0x0100;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- }\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
-\r
- break;\r
-\r
- case P2C_MEM_2:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x24,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x28,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- if (Node->ResType == PciBarTypeMem32) {\r
-\r
- //\r
- // Set non-prefetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl &= 0xfdff;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- } else {\r
-\r
- //\r
- // Set pre-fetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl |= 0x0200;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- }\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
- break;\r
-\r
- case P2C_IO_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x2c,\r
- 1,\r
- &Address\r
- );\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x30,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
-\r
- break;\r
-\r
- case P2C_IO_2:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x34,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x38,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ApplyResourcePadding (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- PCI_RESOURCE_NODE *Node;\r
- UINT8 DummyBarIndex;\r
-\r
- DummyBarIndex = 0;\r
- Ptr = PciDev->ResourcePaddingDescriptors;\r
-\r
- while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
- if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
- if (Ptr->AddrLen != 0) {\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
-\r
- if (Ptr->AddrSpaceGranularity == 32) {\r
-\r
- //\r
- // prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0x6) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypePMem32,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- //\r
- // Non-prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeMem32,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
- }\r
-\r
- if (Ptr->AddrSpaceGranularity == 64) {\r
-\r
- //\r
- // prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0x6) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypePMem64,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- PMem64Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- //\r
- // Non-prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeMem64,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- Mem64Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
- }\r
- }\r
-\r
- Ptr++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Light PCI bus driver woundn't support hotplug root device\r
-// So no need to pad resource for them\r
-//\r
-VOID\r
-GetResourcePaddingPpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get resource.\r
-\r
-Arguments:\r
-\r
- PciIoDevice A pointer to a pci device.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- if (gPciHotPlugInit) {\r
- if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
- GetResourcePaddingForHpb (PciIoDevice);\r
- }\r
- }\r
-}\r