MdePkg: BaseIoLibIntrinsic (IoLib class) library
authorLeo Duran <leo.duran@amd.com>
Wed, 12 Apr 2017 14:55:23 +0000 (22:55 +0800)
committerLiming Gao <liming.gao@intel.com>
Thu, 13 Apr 2017 05:16:00 +0000 (13:16 +0800)
This patch adds an SEV-specific .INF and corresponding assembly
files, to unroll REP INSx/OUTSx on IoRead/WriteFifo#() routines
when the SEV feature is enabled under a hypervisor environment.

The new .INF only supports the IA32 and X64 architectures.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf [new file with mode: 0644]
MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm [new file with mode: 0644]
MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm [new file with mode: 0644]
MdePkg/MdePkg.dsc

diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
new file mode 100644 (file)
index 0000000..0eec896
--- /dev/null
@@ -0,0 +1,59 @@
+## @file\r
+#  Instance of I/O Library using compiler intrinsics.\r
+#\r
+#  I/O Library that uses compiler intrinsics to perform IN and OUT instructions\r
+#  for IA-32 and x64.\r
+#\r
+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+#  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+#  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+#\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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseIoLibIntrinsicSev\r
+  MODULE_UNI_FILE                = BaseIoLibIntrinsic.uni\r
+  FILE_GUID                      = 93742f95-6e71-4581-b600-8e1da443f95a\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = IoLib \r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources]\r
+  IoLibMmioBuffer.c\r
+  BaseIoLibIntrinsicInternal.h\r
+  IoHighLevel.c\r
+\r
+[Sources.IA32]\r
+  IoLibGcc.c    | GCC\r
+  IoLibMsc.c    | MSFT\r
+  IoLibIcc.c    | INTEL\r
+  IoLib.c\r
+  Ia32/IoFifoSev.nasm\r
+\r
+[Sources.X64]\r
+  IoLibGcc.c    | GCC\r
+  IoLibMsc.c    | MSFT\r
+  IoLibIcc.c    | INTEL\r
+  IoLib.c\r
+  X64/IoFifoSev.nasm\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  BaseLib\r
+\r
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm
new file mode 100644 (file)
index 0000000..3e80c17
--- /dev/null
@@ -0,0 +1,299 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+;\r
+; This program and the accompanying materials are licensed and made available\r
+; under the terms and conditions of the BSD License which accompanies this\r
+; 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
+    SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; Check whether we need to unroll the String I/O under SEV guest\r
+;\r
+; Return // eax   (1 - unroll, 0 - no unroll)\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(SevNoRepIo)\r
+ASM_PFX(SevNoRepIo):\r
+\r
+  ; CPUID clobbers ebx, ecx and edx\r
+  push      ebx\r
+  push      ecx\r
+  push      edx\r
+\r
+  ; Check if we are running under hypervisor\r
+  ; CPUID(1).ECX Bit 31\r
+  mov       eax, 1\r
+  cpuid\r
+  bt        ecx, 31\r
+  jnc       @UseRepIo\r
+\r
+  ; Check if we have Memory encryption CPUID leaf\r
+  mov       eax, 0x80000000\r
+  cpuid\r
+  cmp       eax, 0x8000001f\r
+  jl        @UseRepIo\r
+\r
+  ; Check for memory encryption feature:\r
+  ;  CPUID  Fn8000_001F[EAX] - Bit 1\r
+  ;\r
+  mov       eax,  0x8000001f\r
+  cpuid\r
+  bt        eax, 1\r
+  jnc       @UseRepIo\r
+\r
+  ; Check if memory encryption is enabled\r
+  ;  MSR_0xC0010131 - Bit 0 (SEV enabled)\r
+  ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)\r
+  mov       ecx, 0xc0010131\r
+  rdmsr\r
+\r
+  ; Check for (SevEsEnabled == 0 && SevEnabled == 1)\r
+  and       eax, 3\r
+  cmp       eax, 1\r
+  je        @SevNoRepIo_Done\r
+\r
+@UseRepIo:\r
+  xor       eax, eax\r
+\r
+@SevNoRepIo_Done:\r
+  pop       edx\r
+  pop       ecx\r
+  pop       ebx\r
+  ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo8 (\r
+;    IN  UINTN                 Port,\r
+;    IN  UINTN                 Size,\r
+;    OUT VOID                  *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo8)\r
+ASM_PFX(IoReadFifo8):\r
+    push    edi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo8_NoRep\r
+\r
+    cld\r
+    rep     insb\r
+    jmp     @IoReadFifo8_Done\r
+\r
+@IoReadFifo8_NoRep:\r
+    jecxz   @IoReadFifo8_Done\r
+\r
+@IoReadFifo8_Loop:\r
+    in      al, dx\r
+    mov     byte [edi], al\r
+    inc     edi\r
+    loop    @IoReadFifo8_Loop\r
+\r
+@IoReadFifo8_Done:\r
+    pop     edi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo16 (\r
+;    IN  UINTN                 Port,\r
+;    IN  UINTN                 Size,\r
+;    OUT VOID                  *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo16)\r
+ASM_PFX(IoReadFifo16):\r
+    push    edi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo16_NoRep\r
+\r
+    cld\r
+    rep     insw\r
+    jmp     @IoReadFifo16_Done\r
+\r
+@IoReadFifo16_NoRep:\r
+    jecxz   @IoReadFifo16_Done\r
+\r
+@IoReadFifo16_Loop:\r
+    in      ax, dx\r
+    mov     word [edi], ax\r
+    add     edi, 2\r
+    loop    @IoReadFifo16_Loop\r
+\r
+@IoReadFifo16_Done:\r
+    pop     edi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo32 (\r
+;    IN  UINTN                 Port,\r
+;    IN  UINTN                 Size,\r
+;    OUT VOID                  *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo32)\r
+ASM_PFX(IoReadFifo32):\r
+    push    edi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     edi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo32_NoRep\r
+\r
+    cld\r
+    rep     insd\r
+    jmp     @IoReadFifo32_Done\r
+\r
+@IoReadFifo32_NoRep:\r
+    jecxz   @IoReadFifo32_Done\r
+\r
+@IoReadFifo32_Loop:\r
+    in      eax, dx\r
+    mov     dword [edi], eax\r
+    add     edi, 4\r
+    loop    @IoReadFifo32_Loop\r
+\r
+@IoReadFifo32_Done:\r
+    pop     edi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo8 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoWriteFifo8)\r
+ASM_PFX(IoWriteFifo8):\r
+    push    esi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo8_NoRep\r
+\r
+    cld\r
+    rep     outsb\r
+    jmp     @IoWriteFifo8_Done\r
+\r
+@IoWriteFifo8_NoRep:\r
+    jecxz   @IoWriteFifo8_Done\r
+\r
+@IoWriteFifo8_Loop:\r
+    mov     byte [esi], al\r
+    out     dx, al\r
+    inc     esi\r
+    loop    @IoWriteFifo8_Loop\r
+\r
+@IoWriteFifo8_Done:\r
+    pop     esi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo16 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoWriteFifo16)\r
+ASM_PFX(IoWriteFifo16):\r
+    push    esi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo16_NoRep\r
+\r
+    cld\r
+    rep     outsw\r
+    jmp     @IoWriteFifo16_Done\r
+\r
+@IoWriteFifo16_NoRep:\r
+    jecxz   @IoWriteFifo16_Done\r
+\r
+@IoWriteFifo16_Loop:\r
+    mov     word [esi], ax\r
+    out     dx, ax\r
+    add     esi, 2\r
+    loop    @IoWriteFifo16_Loop\r
+\r
+@IoWriteFifo16_Done:\r
+    pop     esi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoWriteFifo32 (\r
+;    IN UINTN                  Port,\r
+;    IN UINTN                  Size,\r
+;    IN VOID                   *Buffer\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoWriteFifo32)\r
+ASM_PFX(IoWriteFifo32):\r
+    push    esi\r
+    mov     dx, [esp + 8]\r
+    mov     ecx, [esp + 12]\r
+    mov     esi, [esp + 16]\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo32_NoRep\r
+\r
+    cld\r
+    rep     outsd\r
+    jmp     @IoWriteFifo32_Done\r
+\r
+@IoWriteFifo32_NoRep:\r
+    jecxz   @IoWriteFifo32_Done\r
+\r
+@IoWriteFifo32_Loop:\r
+    mov     dword [esi], eax\r
+    out     dx, eax\r
+    add     esi, 4\r
+    loop    @IoWriteFifo32_Loop\r
+\r
+@IoWriteFifo32_Done:\r
+    pop     esi\r
+    ret\r
+\r
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm
new file mode 100644 (file)
index 0000000..26e0166
--- /dev/null
@@ -0,0 +1,288 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+;\r
+; This program and the accompanying materials are licensed and made available\r
+; under the terms and conditions of the BSD License which accompanies this\r
+; 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
+    DEFAULT REL\r
+    SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; Check whether we need to unroll the String I/O in SEV guest\r
+;\r
+; Return // eax   (1 - unroll, 0 - no unroll)\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(SevNoRepIo)\r
+ASM_PFX(SevNoRepIo):\r
+\r
+  ; CPUID clobbers ebx, ecx and edx\r
+  push      rbx\r
+  push      rcx\r
+  push      rdx\r
+\r
+  ; Check if we are runing under hypervisor\r
+  ; CPUID(1).ECX Bit 31\r
+  mov       eax, 1\r
+  cpuid\r
+  bt        ecx, 31\r
+  jnc       @UseRepIo\r
+\r
+  ; Check if we have Memory encryption CPUID leaf\r
+  mov       eax, 0x80000000\r
+  cpuid\r
+  cmp       eax, 0x8000001f\r
+  jl        @UseRepIo\r
+\r
+  ; Check for memory encryption feature:\r
+  ;  CPUID  Fn8000_001F[EAX] - Bit 1\r
+  ;\r
+  mov       eax,  0x8000001f\r
+  cpuid\r
+  bt        eax, 1\r
+  jnc       @UseRepIo\r
+\r
+  ; Check if memory encryption is enabled\r
+  ;  MSR_0xC0010131 - Bit 0 (SEV enabled)\r
+  ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)\r
+  mov       ecx, 0xc0010131\r
+  rdmsr\r
+\r
+  ; Check for (SevEsEnabled == 0 && SevEnabled == 1)\r
+  and       eax, 3\r
+  cmp       eax, 1\r
+  je        @SevNoRepIo_Done\r
+\r
+@UseRepIo:\r
+  xor       eax, eax\r
+\r
+@SevNoRepIo_Done:\r
+  pop       rdx\r
+  pop       rcx\r
+  pop       rbx\r
+  ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo8 (\r
+;    IN  UINTN                 Port,              // rcx\r
+;    IN  UINTN                 Size,              // rdx\r
+;    OUT VOID                  *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo8)\r
+ASM_PFX(IoReadFifo8):\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo8_NoRep\r
+\r
+    cld\r
+    rep     insb\r
+    jmp     @IoReadFifo8_Done\r
+\r
+@IoReadFifo8_NoRep:\r
+    jrcxz   @IoReadFifo8_Done\r
+\r
+@IoReadFifo8_Loop:\r
+    in      al, dx\r
+    mov     byte [rdi], al\r
+    inc     rdi\r
+    loop    @IoReadFifo8_Loop\r
+\r
+@IoReadFifo8_Done:\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo16 (\r
+;    IN  UINTN                 Port,              // rcx\r
+;    IN  UINTN                 Size,              // rdx\r
+;    OUT VOID                  *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo16)\r
+ASM_PFX(IoReadFifo16):\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo16_NoRep\r
+\r
+    cld\r
+    rep     insw\r
+    jmp     @IoReadFifo16_Done\r
+\r
+@IoReadFifo16_NoRep:\r
+    jrcxz   @IoReadFifo16_Done\r
+\r
+@IoReadFifo16_Loop:\r
+    in      ax, dx\r
+    mov     word [rdi], ax\r
+    add     rdi, 2\r
+    loop    @IoReadFifo16_Loop\r
+\r
+@IoReadFifo16_Done:\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\r
+\r
+;------------------------------------------------------------------------------\r
+;  VOID\r
+;  EFIAPI\r
+;  IoReadFifo32 (\r
+;    IN  UINTN                 Port,              // rcx\r
+;    IN  UINTN                 Size,              // rdx\r
+;    OUT VOID                  *Buffer            // r8\r
+;    );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(IoReadFifo32)\r
+ASM_PFX(IoReadFifo32):\r
+    xchg    rcx, rdx\r
+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoReadFifo32_NoRep\r
+\r
+    cld\r
+    rep     insd\r
+    jmp     @IoReadFifo32_Done\r
+\r
+@IoReadFifo32_NoRep:\r
+    jrcxz   @IoReadFifo32_Done\r
+\r
+@IoReadFifo32_Loop:\r
+    in      eax, dx\r
+    mov     dword [rdi], eax\r
+    add     rdi, 4\r
+    loop    @IoReadFifo32_Loop\r
+\r
+@IoReadFifo32_Done:\r
+    mov     rdi, r8             ; restore rdi\r
+    ret\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
+global ASM_PFX(IoWriteFifo8)\r
+ASM_PFX(IoWriteFifo8):\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo8_NoRep\r
+\r
+    cld\r
+    rep     outsb\r
+    jmp     @IoWriteFifo8_Done\r
+\r
+@IoWriteFifo8_NoRep:\r
+    jrcxz   @IoWriteFifo8_Done\r
+\r
+@IoWriteFifo8_Loop:\r
+    mov     byte [rsi], al\r
+    out     dx, al\r
+    inc     rsi\r
+    loop    @IoWriteFifo8_Loop\r
+\r
+@IoWriteFifo8_Done:\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\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
+global ASM_PFX(IoWriteFifo16)\r
+ASM_PFX(IoWriteFifo16):\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo16_NoRep\r
+\r
+    cld\r
+    rep     outsw\r
+    jmp     @IoWriteFifo16_Done\r
+\r
+@IoWriteFifo16_NoRep:\r
+    jrcxz   @IoWriteFifo16_Done\r
+\r
+@IoWriteFifo16_Loop:\r
+    mov     word [rsi], ax\r
+    out     dx, ax\r
+    add     rsi, 2\r
+    loop    @IoWriteFifo16_Loop\r
+\r
+@IoWriteFifo16_Done:\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\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
+global ASM_PFX(IoWriteFifo32)\r
+ASM_PFX(IoWriteFifo32):\r
+    xchg    rcx, rdx\r
+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi\r
+\r
+    ; Check if we need to unroll String I/O\r
+    call    ASM_PFX(SevNoRepIo)\r
+    test    eax, eax\r
+    jnz     @IoWriteFifo32_NoRep\r
+\r
+    cld\r
+    rep     outsd\r
+    jmp     @IoWriteFifo32_Done\r
+\r
+@IoWriteFifo32_NoRep:\r
+    jrcxz   @IoWriteFifo32_Done\r
+\r
+@IoWriteFifo32_Loop:\r
+    mov     dword [rsi], eax\r
+    out     dx, eax\r
+    add     rsi, 4\r
+    loop    @IoWriteFifo32_Loop\r
+\r
+@IoWriteFifo32_Done:\r
+    mov     rsi, r8             ; restore rsi\r
+    ret\r
+\r
index 2144979..8b69de3 100644 (file)
 \r
 [Components.IA32, Components.X64]\r
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
+  MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf\r
   MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf\r
   MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf\r
   MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf\r