]> git.proxmox.com Git - mirror_edk2.git/blobdiff - PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
PcAtChipsetPkg/PciHostBridgeDxe: Improve KVM FIFO I/O read/write performance
[mirror_edk2.git] / PcAtChipsetPkg / PciHostBridgeDxe / PciRootBridgeIo.c
index edbe4a03b2a1d9bf2031fda802633724c913c9bc..b4da52eefe076899eb46dc440d47570378900f16 100644 (file)
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/ \r
 \r
 #include "PciHostBridge.h"\r
+#include "IoFifo.h"\r
 \r
 typedef struct {\r
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];\r
@@ -145,7 +146,7 @@ RootBridgeIoMemRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -162,7 +163,7 @@ RootBridgeIoMemRead (
                           responsible for aligning the Address if required.\r
    @param[in]   Count     The number of memory operations to perform. Bytes moved is\r
                           Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For\r
                           write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -177,7 +178,7 @@ RootBridgeIoMemWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -185,11 +186,11 @@ RootBridgeIoMemWrite (
 \r
    @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]   Width       Signifies the width of the memory operations.\r
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for\r
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for\r
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For\r
                             write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.\r
@@ -205,7 +206,7 @@ RootBridgeIoIoRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 UserAddress,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *UserBuffer\r
+  OUT    VOID                                   *UserBuffer\r
   );\r
 \r
 /**\r
@@ -213,11 +214,11 @@ RootBridgeIoIoRead (
 \r
    @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]   Width       Signifies the width of the memory operations.\r
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for\r
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for\r
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For\r
                             write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.\r
@@ -233,7 +234,7 @@ RootBridgeIoIoWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 UserAddress,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *UserBuffer\r
+  IN     VOID                                   *UserBuffer\r
   );\r
 \r
 /**\r
@@ -300,7 +301,7 @@ RootBridgeIoPciRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -317,7 +318,7 @@ RootBridgeIoPciRead (
    @param[in]   Address   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count     The number of PCI configuration operations to perform. Bytes\r
                           moved is Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For\r
                           write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -333,7 +334,7 @@ RootBridgeIoPciWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -346,7 +347,7 @@ RootBridgeIoPciWrite (
    @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.\r
    @param[in]       HostAddress     The system memory address to map to the PCI controller.\r
-   @param[in][out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
+   @param[inout]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
    @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use\r
                                     to access the system memory's HostAddress.\r
    @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.\r
@@ -523,9 +524,9 @@ RootBridgeIoGetAttributes (
                                     MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
                                     MEMORY_DISABLE are not set, then ResourceBase and\r
                                     ResourceLength are ignored, and may be NULL.\r
-   @param[in][out]  ResourceBase    A pointer to the base address of the resource range to be modified\r
+   @param[inout]  ResourceBase    A pointer to the base address of the resource range to be modified\r
                                     by the attributes specified by Attributes.\r
-   @param[in][out]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
+   @param[inout]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
                                     attributes specified by Attributes.\r
    \r
    @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.\r
@@ -674,8 +675,11 @@ RootBridgeConstructor (
 \r
   PrivateData->RootBridgeAttrib = Attri;\r
   \r
-  PrivateData->Attributes  = 0;\r
-  PrivateData->Supports    = 0;\r
+  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \\r
+                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \\r
+                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \\r
+                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
+  PrivateData->Attributes  = PrivateData->Supports;\r
 \r
   Protocol->ParentHandle   = HostBridgeHandle;\r
   \r
@@ -866,7 +870,7 @@ RootBridgeIoCheckParameter (
    @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
                               moved is Width size * Count, starting at Address.\r
-   @param[out]  UserBuffer    For read operations, the destination buffer to store the results. For\r
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
                               write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -914,6 +918,13 @@ RootBridgeIoMemRW (
         case EfiPciWidthUint64:\r
           MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     } else {\r
       switch (OperationWidth) {\r
@@ -929,6 +940,13 @@ RootBridgeIoMemRW (
         case EfiPciWidthUint64:\r
           *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     }\r
   }\r
@@ -944,7 +962,7 @@ RootBridgeIoMemRW (
    @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
                               moved is Width size * Count, starting at Address.\r
-   @param[out]  UserBuffer    For read operations, the destination buffer to store the results. For\r
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
                               write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -977,6 +995,51 @@ RootBridgeIoIoRW (
   InStride = mInStride[Width];\r
   OutStride = mOutStride[Width];\r
   OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
+  if (InStride == 0) {\r
+    if (Write) {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          IoWriteFifo8 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        case EfiPciWidthUint16:\r
+          IoWriteFifo16 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        case EfiPciWidthUint32:\r
+          IoWriteFifo32 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    } else {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          IoReadFifo8 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        case EfiPciWidthUint16:\r
+          IoReadFifo16 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        case EfiPciWidthUint32:\r
+          IoReadFifo32 ((UINTN) Address, Count, Buffer);\r
+          return EFI_SUCCESS;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    }\r
+  }\r
+#endif\r
+\r
   for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
     if (Write) {\r
       switch (OperationWidth) {\r
@@ -989,6 +1052,13 @@ RootBridgeIoIoRW (
         case EfiPciWidthUint32:\r
           IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     } else {\r
       switch (OperationWidth) {\r
@@ -1001,6 +1071,13 @@ RootBridgeIoIoRW (
         case EfiPciWidthUint32:\r
           *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     }\r
   }\r
@@ -1016,7 +1093,7 @@ RootBridgeIoIoRW (
    @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
                               moved is Width size * Count, starting at Address.\r
-   @param[out]  UserBuffer    For read operations, the destination buffer to store the results. For\r
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
                               write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -1074,6 +1151,13 @@ RootBridgeIoPciRW (
         case EfiPciWidthUint32:\r
           PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     } else {\r
       switch (OperationWidth) {\r
@@ -1086,6 +1170,13 @@ RootBridgeIoPciRW (
         case EfiPciWidthUint32:\r
           *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);\r
           break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
       }\r
     }\r
   }\r
@@ -1177,7 +1268,7 @@ RootBridgeIoPollMem (
     }\r
     NumberOfTicks += 1;\r
   \r
-    while (NumberOfTicks) {\r
+    while (NumberOfTicks != 0) {\r
 \r
       mMetronome->WaitForTick (mMetronome, 1);\r
     \r
@@ -1278,7 +1369,7 @@ RootBridgeIoPollIo (
     }\r
     NumberOfTicks += 1;\r
   \r
-    while (NumberOfTicks) {\r
+    while (NumberOfTicks != 0) {\r
 \r
       mMetronome->WaitForTick (mMetronome, 1);\r
     \r
@@ -1327,7 +1418,7 @@ RootBridgeIoMemRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   )\r
 {\r
   return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);\r
@@ -1347,7 +1438,7 @@ RootBridgeIoMemRead (
                           responsible for aligning the Address if required.\r
    @param[in]   Count     The number of memory operations to perform. Bytes moved is\r
                           Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For\r
                           write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -1362,7 +1453,7 @@ RootBridgeIoMemWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   )\r
 {\r
   return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);  \r
@@ -1393,7 +1484,7 @@ RootBridgeIoIoRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   )\r
 {\r
   return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);  \r
@@ -1408,7 +1499,7 @@ RootBridgeIoIoRead (
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[in]   Buffer       For read operations, the destination buffer to store the results. For\r
                             write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.\r
@@ -1424,7 +1515,7 @@ RootBridgeIoIoWrite (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,\r
   IN       UINT64                                  Address,\r
   IN       UINTN                                   Count,\r
-  IN OUT   VOID                                    *Buffer\r
+  IN       VOID                                    *Buffer\r
   )\r
 {\r
   return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);  \r
@@ -1457,7 +1548,7 @@ RootBridgeIoIoWrite (
 EFI_STATUS\r
 EFIAPI\r
 RootBridgeIoCopyMem (\r
-  IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *This,\r
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,\r
   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,\r
   IN UINT64                                       DestAddress,\r
   IN UINT64                                       SrcAddress,\r
@@ -1549,7 +1640,7 @@ RootBridgeIoPciRead (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN       UINT64                                 Address,\r
   IN       UINTN                                  Count,\r
-  IN OUT   VOID                                   *Buffer\r
+  OUT      VOID                                   *Buffer\r
   )\r
 {\r
   return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
@@ -1569,7 +1660,7 @@ RootBridgeIoPciRead (
    @param[in]   Address   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count     The number of PCI configuration operations to perform. Bytes\r
                           moved is Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For\r
                           write operations, the source buffer to write data from.\r
    \r
    @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
@@ -1585,7 +1676,7 @@ RootBridgeIoPciWrite (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN       UINT64                                 Address,\r
   IN       UINTN                                  Count,\r
-  IN OUT   VOID                                   *Buffer\r
+  IN       VOID                                   *Buffer\r
   )\r
 {\r
   return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
@@ -1601,7 +1692,7 @@ RootBridgeIoPciWrite (
    @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.\r
    @param[in]       HostAddress     The system memory address to map to the PCI controller.\r
-   @param[in][out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
+   @param[inout]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
    @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use\r
                                     to access the system memory's HostAddress.\r
    @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.\r
@@ -1830,7 +1921,7 @@ RootBridgeIoAllocateBuffer (
   //\r
   // Validate Attributes\r
   //\r
-  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {\r
+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1958,11 +2049,11 @@ RootBridgeIoGetAttributes (
   //\r
   // Set the return value for Supported and Attributes\r
   //\r
-  if (Supported) {\r
+  if (Supported != NULL) {\r
     *Supported  = PrivateData->Supports; \r
   }\r
 \r
-  if (Attributes) {\r
+  if (Attributes != NULL) {\r
     *Attributes = PrivateData->Attributes;\r
   }\r
   \r
@@ -1989,9 +2080,9 @@ RootBridgeIoGetAttributes (
                                     MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
                                     MEMORY_DISABLE are not set, then ResourceBase and\r
                                     ResourceLength are ignored, and may be NULL.\r
-   @param[in][out]  ResourceBase    A pointer to the base address of the resource range to be modified\r
+   @param[inout]  ResourceBase    A pointer to the base address of the resource range to be modified\r
                                     by the attributes specified by Attributes.\r
-   @param[in][out]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
+   @param[inout]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
                                     attributes specified by Attributes.\r
    \r
    @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.\r
@@ -2012,7 +2103,7 @@ RootBridgeIoSetAttributes (
   \r
   PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
   \r
-  if (Attributes) {\r
+  if (Attributes != 0) {\r
     if ((Attributes & (~(PrivateData->Supports))) != 0) {\r
       return EFI_UNSUPPORTED;\r
     }\r