}\r
\r
//\r
+ // Add VF resource\r
+ //\r
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+\r
+ switch ((PciDev->VfPciBar)[Index].BarType) {\r
+\r
+ case PciBarTypeMem32:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem64Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypePMem64:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem64Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypePMem32:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ Node\r
+ );\r
+ break;\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ break;\r
+\r
+ case PciBarTypeUnknown:\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
// If there is no resource requested from this device,\r
// then we indicate this device has been allocated naturally.\r
//\r
return Node;\r
}\r
\r
+/**\r
+ This function is used to create a IOV VF resource node.\r
+\r
+ @param PciDev Pci device instance.\r
+ @param Length Length of Io/Memory resource.\r
+ @param Alignment Alignment of resource.\r
+ @param Bar Bar index.\r
+ @param ResType Type of resource: IO/Memory.\r
+ @param ResUsage Resource usage.\r
+\r
+ @return PCI resource node created for given VF PCI device.\r
+ NULL means PCI resource node is not created.\r
+\r
+**/\r
+PCI_RESOURCE_NODE *\r
+CreateVfResourceNode (\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
+ PCI_RESOURCE_NODE *Node;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n",\r
+ (UINTN)PciDev->BusNumber,\r
+ (UINTN)PciDev->DeviceNumber,\r
+ (UINTN)PciDev->FunctionNumber,\r
+ (UINTN)Bar,\r
+ (UINTN)ResType,\r
+ (UINTN)Length\r
+ ));\r
+\r
+ Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage);\r
+ if (Node == NULL) {\r
+ return Node;\r
+ }\r
+\r
+ Node->Virtual = TRUE;\r
+\r
+ return Node;\r
+}\r
+\r
/**\r
This function is used to extract resource request from\r
device node list.\r
UINT64 Address;\r
UINT32 Address32;\r
\r
+ //\r
+ // Check VF BAR\r
+ //\r
+ if (Node->Virtual) {\r
+ ProgramVfBar (Base, Node);\r
+ }\r
+\r
Address = 0;\r
PciIo = &(Node->PciDev->PciIo);\r
\r
}\r
}\r
\r
+/**\r
+ Program IOV VF Bar register for PCI device.\r
+\r
+ @param Base Base address for PCI device resource to be progammed.\r
+ @param Node Point to resoure node structure.\r
+\r
+**/\r
+EFI_STATUS\r
+ProgramVfBar (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 Address;\r
+ UINT32 Address32;\r
+\r
+ ASSERT (Node->Virtual);\r
+ if (!Node->Virtual) {\r
+ return EFI_UNSUPPORTED;\r
+ }\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->VfPciBar[Node->Bar]).BarType) {\r
+\r
+ case PciBarTypeMem32:\r
+ case PciBarTypePMem32:\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n",\r
+ (UINTN)Node->PciDev->BusNumber,\r
+ (UINTN)Node->PciDev->DeviceNumber,\r
+ (UINTN)Node->PciDev->FunctionNumber,\r
+ (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ (UINTN)Address\r
+ ));\r
+\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+ case PciBarTypePMem64:\r
+\r
+ Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) RShiftU64 (Address, 32);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ ((Node->PciDev->VfPciBar[Node->Bar]).Offset + 4),\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n",\r
+ (UINTN)Node->PciDev->BusNumber,\r
+ (UINTN)Node->PciDev->DeviceNumber,\r
+ (UINTN)Node->PciDev->FunctionNumber,\r
+ (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ (UINT64)Address\r
+ ));\r
+\r
+ break;\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Program PCI-PCI bridge apperture.\r
\r