]> git.proxmox.com Git - mirror_edk2.git/commitdiff
PcAtChipsetPkg/PciHostBridgeDxe: Improve KVM FIFO I/O read/write performance
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 1 Jun 2012 17:07:00 +0000 (17:07 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 1 Jun 2012 17:07:00 +0000 (17:07 +0000)
KVM can substantially boost the speed of the rep insb/insw/insl
and rep outsb/outsw/outsl instructions by transferring up to
a page of data per VM trap.

This change adds assembly handling of the PCI Host Bridge
I/O FIFO Reads and Writes.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13424 6f19259b-4bc3-4df7-8a09-765794883524

PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S [new file with mode: 0644]
PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm [new file with mode: 0644]
PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h [new file with mode: 0644]
PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf
PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S [new file with mode: 0644]
PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm [new file with mode: 0644]

diff --git a/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S b/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S
new file mode 100644 (file)
index 0000000..6b9c096
--- /dev/null
@@ -0,0 +1,133 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+# 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
+#------------------------------------------------------------------------------\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo8 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo8)\r
+ASM_PFX(IoReadFifo8):\r
+    push    %edi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %edi\r
+rep insb\r
+    pop     %edi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo16 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo16)\r
+ASM_PFX(IoReadFifo16):\r
+    push    %edi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %edi\r
+rep insw\r
+    pop     %edi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo32 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo32)\r
+ASM_PFX(IoReadFifo32):\r
+    push    %edi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %edi\r
+rep insl\r
+    pop     %edi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo8 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo8)\r
+ASM_PFX(IoWriteFifo8):\r
+    push    %esi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %esi\r
+rep outsb\r
+    pop     %esi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo16 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo16)\r
+ASM_PFX(IoWriteFifo16):\r
+    push    %esi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %esi\r
+rep outsw\r
+    pop     %esi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo32 (\r
+#    IN UINTN                  Port,\r
+#    IN UINTN                  Count,\r
+#    IN VOID                   *Buffer\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo32)\r
+ASM_PFX(IoWriteFifo32):\r
+    push    %esi\r
+    cld\r
+    movw    8(%esp), %dx\r
+    mov     12(%esp), %ecx\r
+    mov     16(%esp), %esi\r
+rep outsl\r
+    pop     %esi\r
+    ret\r
+\r
diff --git a/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm b/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm
new file mode 100644 (file)
index 0000000..4b147cb
--- /dev/null
@@ -0,0 +1,139 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+; 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
+;------------------------------------------------------------------------------\r
+\r
+    .586P\r
+    .model  flat,C\r
+    .code\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo8 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo8 PROC\r
+    push    edi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+rep insb\r
+    pop     edi\r
+    ret\r
+IoReadFifo8 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo16 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo16 PROC\r
+    push    edi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+rep insw\r
+    pop     edi\r
+    ret\r
+IoReadFifo16 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo32 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo32 PROC\r
+    push    edi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+rep insd\r
+    pop     edi\r
+    ret\r
+IoReadFifo32 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo8 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo8 PROC\r
+    push    esi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+rep outsb\r
+    pop     esi\r
+    ret\r
+IoWriteFifo8 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo16 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo16 PROC\r
+    push    esi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+rep outsw\r
+    pop     esi\r
+    ret\r
+IoWriteFifo16 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo32 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo32 PROC\r
+    push    esi\r
+    cld\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+rep outsd\r
+    pop     esi\r
+    ret\r
+IoWriteFifo32 ENDP\r
+\r
+    END\r
+\r
diff --git a/PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h b/PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h
new file mode 100644 (file)
index 0000000..c4eb208
--- /dev/null
@@ -0,0 +1,175 @@
+/** @file
+  I/O FIFO routines
+
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+  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
+  
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/ 
+
+#ifndef _IO_FIFO_H_INCLUDED_
+#define _IO_FIFO_H_INCLUDED_
+
+/**
+  Reads an 8-bit I/O port fifo into a block of memory.
+
+  Reads the 8-bit I/O fifo port specified by Port.
+
+  The port is read Count times, and the read data is
+  stored in the provided Buffer.
+
+  This function must guarantee that all I/O read and write operations are
+  serialized.
+
+  If 8-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to read.
+  @param  Count   The number of times to read I/O port.
+  @param  Buffer  The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+IoReadFifo8 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+/**
+  Reads a 16-bit I/O port fifo into a block of memory.
+
+  Reads the 16-bit I/O fifo port specified by Port.
+
+  The port is read Count times, and the read data is
+  stored in the provided Buffer.
+
+  This function must guarantee that all I/O read and write operations are
+  serialized.
+
+  If 16-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to read.
+  @param  Count   The number of times to read I/O port.
+  @param  Buffer  The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+IoReadFifo16 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+/**
+  Reads a 32-bit I/O port fifo into a block of memory.
+
+  Reads the 32-bit I/O fifo port specified by Port.
+
+  The port is read Count times, and the read data is
+  stored in the provided Buffer.
+
+  This function must guarantee that all I/O read and write operations are
+  serialized.
+
+  If 32-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to read.
+  @param  Count   The number of times to read I/O port.
+  @param  Buffer  The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+IoReadFifo32 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+/**
+  Writes a block of memory into an 8-bit I/O port fifo.
+
+  Writes the 8-bit I/O fifo port specified by Port.
+
+  The port is written Count times, and the write data is
+  retrieved from the provided Buffer.
+
+  This function must guarantee that all I/O write and write operations are
+  serialized.
+
+  If 8-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to write.
+  @param  Count   The number of times to write I/O port.
+  @param  Buffer  The buffer to store the write data into.
+
+**/
+VOID
+EFIAPI
+IoWriteFifo8 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+/**
+  Writes a block of memory into a 16-bit I/O port fifo.
+
+  Writes the 16-bit I/O fifo port specified by Port.
+
+  The port is written Count times, and the write data is
+  retrieved from the provided Buffer.
+
+  This function must guarantee that all I/O write and write operations are
+  serialized.
+
+  If 16-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to write.
+  @param  Count   The number of times to write I/O port.
+  @param  Buffer  The buffer to store the write data into.
+
+**/
+VOID
+EFIAPI
+IoWriteFifo16 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+/**
+  Writes a block of memory into a 32-bit I/O port fifo.
+
+  Writes the 32-bit I/O fifo port specified by Port.
+
+  The port is written Count times, and the write data is
+  retrieved from the provided Buffer.
+
+  This function must guarantee that all I/O write and write operations are
+  serialized.
+
+  If 32-bit I/O port operations are not supported, then ASSERT().
+
+  @param  Port    The I/O port to write.
+  @param  Count   The number of times to write I/O port.
+  @param  Buffer  The buffer to store the write data into.
+
+**/
+VOID
+EFIAPI
+IoWriteFifo32 (
+  IN      UINTN                     Port,
+  IN      UINTN                     Count,
+  OUT     VOID                      *Buffer
+  );
+
+#endif
+
index c5fe0fa61aacd14919d765562b3e05038d71b662..ca136a00205fb1695ae9e19513218a0df3060bb9 100644 (file)
   PciRootBridgeIo.c\r
   PciHostBridge.h\r
 \r
   PciRootBridgeIo.c\r
   PciHostBridge.h\r
 \r
+[Sources.IA32]\r
+  Ia32/IoFifo.asm\r
+  Ia32/IoFifo.S\r
+\r
+[Sources.X64]\r
+  X64/IoFifo.asm\r
+  X64/IoFifo.S\r
+\r
 [Protocols]\r
   gEfiPciHostBridgeResourceAllocationProtocolGuid\r
   gEfiPciRootBridgeIoProtocolGuid\r
 [Protocols]\r
   gEfiPciHostBridgeResourceAllocationProtocolGuid\r
   gEfiPciRootBridgeIoProtocolGuid\r
index 512a5049c117fe46337dd06a1d7f171578fa47ba..b4da52eefe076899eb46dc440d47570378900f16 100644 (file)
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/ \r
 \r
 #include "PciHostBridge.h"\r
 **/ \r
 \r
 #include "PciHostBridge.h"\r
+#include "IoFifo.h"\r
 \r
 typedef struct {\r
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];\r
 \r
 typedef struct {\r
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];\r
@@ -994,6 +995,51 @@ RootBridgeIoIoRW (
   InStride = mInStride[Width];\r
   OutStride = mOutStride[Width];\r
   OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
   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
   for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
     if (Write) {\r
       switch (OperationWidth) {\r
diff --git a/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S b/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S
new file mode 100644 (file)
index 0000000..ca484f5
--- /dev/null
@@ -0,0 +1,121 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+# 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
+#------------------------------------------------------------------------------\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo8 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo8)\r
+ASM_PFX(IoReadFifo8):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register\r
+rep insb\r
+    mov     %r8, %rdi           # restore rdi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo16 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo16)\r
+ASM_PFX(IoReadFifo16):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register\r
+rep insw\r
+    mov     %r8, %rdi           # restore rdi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoReadFifo32 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoReadFifo32)\r
+ASM_PFX(IoReadFifo32):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register\r
+rep insl\r
+    mov     %r8, %rdi           # restore rdi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo8 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo8)\r
+ASM_PFX(IoWriteFifo8):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register\r
+rep outsb\r
+    mov     %r8, %rsi           # restore rsi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo16 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo16)\r
+ASM_PFX(IoWriteFifo16):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register\r
+rep outsw\r
+    mov     %r8, %rsi           # restore rsi\r
+    ret\r
+\r
+#------------------------------------------------------------------------------\r
+#  VOID\r
+#  EFIAPI\r
+#  IoWriteFifo32 (\r
+#    IN UINTN                  Port,              // rcx\r
+#    IN UINTN                  Count,             // rdx\r
+#    IN VOID                   *Buffer            // r8\r
+#    );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(IoWriteFifo32)\r
+ASM_PFX(IoWriteFifo32):\r
+    cld\r
+    xchg    %rcx, %rdx\r
+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register\r
+rep outsl\r
+    mov     %r8, %rsi           # restore rsi\r
+    ret\r
+\r
diff --git a/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm b/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm
new file mode 100644 (file)
index 0000000..d16f024
--- /dev/null
@@ -0,0 +1,125 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+; 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
+;------------------------------------------------------------------------------\r
+\r
+    .code\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo8 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo8 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+rep insb\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\r
+IoReadFifo8 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo16 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo16 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+rep insw\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\r
+IoReadFifo16 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo32 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoReadFifo32 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+rep insd\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\r
+IoReadFifo32 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo8 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo8 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+rep outsb\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\r
+IoWriteFifo8 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo16 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo16 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+rep outsw\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\r
+IoWriteFifo16 ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo32 (\r
+;    IN UINTN                  Port,              // rcx\r
+;    IN UINTN                  Size,              // rdx\r
+;    IN VOID                   *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+IoWriteFifo32 PROC\r
+    cld\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+rep outsd\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\r
+IoWriteFifo32 ENDP\r
+\r
+    END\r
+\r