* [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library @ 2017-04-06 14:48 Leo Duran 2017-04-06 14:48 ` Leo Duran 0 siblings, 1 reply; 3+ messages in thread From: Leo Duran @ 2017-04-06 14:48 UTC (permalink / raw) To: edk2-devel; +Cc: Leo Duran 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. This patch follows the series "[PATCH v3 00/10] IoLib class library", which has already being pushed upstream. Changes since v6: - Add .INF entry into MdePkg.dsc NOTE: Please pardon the churn... Just had too many balls in the air. (hopefuly this is it, promise!) Leo Duran (1): MdePkg: BaseIoLibIntrinsic (IoLib class) library .../BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf | 59 +++++ .../Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm | 293 +++++++++++++++++++++ .../Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm | 282 ++++++++++++++++++++ MdePkg/MdePkg.dsc | 1 + 4 files changed, 635 insertions(+) create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm -- 2.7.4 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library 2017-04-06 14:48 [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library Leo Duran @ 2017-04-06 14:48 ` Leo Duran 2017-04-06 14:51 ` Gao, Liming 0 siblings, 1 reply; 3+ messages in thread From: Leo Duran @ 2017-04-06 14:48 UTC (permalink / raw) To: edk2-devel; +Cc: Leo Duran, Michael D Kinney, Liming Gao, Brijesh Singh 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> --- .../BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf | 59 +++++ .../Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm | 293 +++++++++++++++++++++ .../Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm | 282 ++++++++++++++++++++ MdePkg/MdePkg.dsc | 1 + 4 files changed, 635 insertions(+) create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf new file mode 100644 index 0000000..0eec896 --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf @@ -0,0 +1,59 @@ +## @file +# Instance of I/O Library using compiler intrinsics. +# +# I/O Library that uses compiler intrinsics to perform IN and OUT instructions +# for IA-32 and x64. +# +# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> +# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> +# Copyright (c) 2017, AMD Incorporated. 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseIoLibIntrinsicSev + MODULE_UNI_FILE = BaseIoLibIntrinsic.uni + FILE_GUID = 93742f95-6e71-4581-b600-8e1da443f95a + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = IoLib + + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + IoLibMmioBuffer.c + BaseIoLibIntrinsicInternal.h + IoHighLevel.c + +[Sources.IA32] + IoLibGcc.c | GCC + IoLibMsc.c | MSFT + IoLibIcc.c | INTEL + IoLib.c + Ia32/IoFifoSev.nasm + +[Sources.X64] + IoLibGcc.c | GCC + IoLibMsc.c | MSFT + IoLibIcc.c | INTEL + IoLib.c + X64/IoFifoSev.nasm + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + BaseLib + diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm new file mode 100644 index 0000000..9adb972 --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm @@ -0,0 +1,293 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> +; Copyright (c) 2017, AMD Incorporated. 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. +; +;------------------------------------------------------------------------------ + + SECTION .text + +;------------------------------------------------------------------------------ +; Check whether we need to unroll the String I/O under SEV guest +; +; Return // eax (1 - unroll, 0 - no unroll) +;------------------------------------------------------------------------------ +global ASM_PFX(SevNoRepIo) +ASM_PFX(SevNoRepIo): + + ; CPUID clobbers ebx, ecx and edx + push ebx + push ecx + push edx + + ; Check if we are running under hypervisor + ; CPUID(1).ECX Bit 31 + mov eax, 1 + cpuid + bt ecx, 31 + jnc @UseRepIo + + ; Check if we have Memory encryption CPUID leaf + mov eax, 0x80000000 + cpuid + cmp eax, 0x8000001f + jl @UseRepIo + + ; Check for memory encryption feature: + ; CPUID Fn8000_001F[EAX] - Bit 1 + ; + mov eax, 0x8000001f + cpuid + bt eax, 1 + jnc @UseRepIo + + ; Check if memory encryption is enabled + ; MSR_0xC0010131 - Bit 0 (SEV enabled) + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) + mov ecx, 0xc0010131 + rdmsr + + ; Check for (SevEsEnabled == 0 && SevEnabled == 1) + and eax, 3 + cmp eax, 1 + je @SevNoRepIo_Done + +@UseRepIo: + xor eax, eax + +@SevNoRepIo_Done: + pop edx + pop ecx + pop ebx + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo8 ( +; IN UINTN Port, +; IN UINTN Size, +; OUT VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo8) +ASM_PFX(IoReadFifo8): + push edi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov edi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll the rep + test eax, eax + jnz @IoReadFifo8_NoRep + + cld + rep insb + jmp @IoReadFifo8_Done + +@IoReadFifo8_NoRep: + jecxz @IoReadFifo8_Done + +@IoReadFifo8_Loop: + in al, dx + mov byte [edi], al + inc edi + loop @IoReadFifo8_Loop + +@IoReadFifo8_Done: + pop edi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo16 ( +; IN UINTN Port, +; IN UINTN Size, +; OUT VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo16) +ASM_PFX(IoReadFifo16): + push edi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov edi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll the rep + test eax, eax + jnz @IoReadFifo16_NoRep + + cld + rep insw + jmp @IoReadFifo16_Done + +@IoReadFifo16_NoRep: + jecxz @IoReadFifo16_Done + +@IoReadFifo16_Loop: + in ax, dx + mov word [edi], ax + add edi, 2 + loop @IoReadFifo16_Loop + +@IoReadFifo16_Done: + pop edi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo32 ( +; IN UINTN Port, +; IN UINTN Size, +; OUT VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo32) +ASM_PFX(IoReadFifo32): + push edi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov edi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll the rep + test eax, eax + jnz @IoReadFifo32_NoRep + + cld + rep insd + jmp @IoReadFifo32_Done + +@IoReadFifo32_NoRep: + jecxz @IoReadFifo32_Done + +@IoReadFifo32_Loop: + in eax, dx + mov dword [edi], eax + add edi, 4 + loop @IoReadFifo32_Loop + +@IoReadFifo32_Done: + pop edi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo8 ( +; IN UINTN Port, +; IN UINTN Size, +; IN VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo8) +ASM_PFX(IoWriteFifo8): + push esi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov esi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo8_NoRep + + cld + rep outsb + jmp @IoWriteFifo8_Done + +@IoWriteFifo8_NoRep: + jecxz @IoWriteFifo8_Done + +@IoWriteFifo8_Loop: + mov byte [esi], al + out dx, al + inc esi + loop @IoWriteFifo8_Loop + +@IoWriteFifo8_Done: + pop esi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo16 ( +; IN UINTN Port, +; IN UINTN Size, +; IN VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo16) +ASM_PFX(IoWriteFifo16): + push esi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov esi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo16_NoRep + + cld + rep outsw + jmp @IoWriteFifo16_Done + +@IoWriteFifo16_NoRep: + jecxz @IoWriteFifo16_Done + +@IoWriteFifo16_Loop: + mov word [esi], ax + out dx, ax + add esi, 2 + loop @IoWriteFifo16_Loop + +@IoWriteFifo16_Done: + pop esi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo32 ( +; IN UINTN Port, +; IN UINTN Size, +; IN VOID *Buffer +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo32) +ASM_PFX(IoWriteFifo32): + push esi + mov dx, [esp + 8] + mov ecx, [esp + 12] + mov esi, [esp + 16] + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo32_NoRep + + cld + rep outsd + jmp @IoWriteFifo32_Done + +@IoWriteFifo32_NoRep: + jecxz @IoWriteFifo32_Done + +@IoWriteFifo32_Loop: + mov dword [esi], eax + out dx, eax + add esi, 4 + loop @IoWriteFifo32_Loop + +@IoWriteFifo32_Done: + pop esi + ret + diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm new file mode 100644 index 0000000..20e3e64 --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm @@ -0,0 +1,282 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> +; Copyright (c) 2017, AMD Incorporated. 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. +; +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; Check whether we need to unroll the String I/O in SEV guest +; +; Return // eax (1 - unroll, 0 - no unroll) +;------------------------------------------------------------------------------ +global ASM_PFX(SevNoRepIo) +ASM_PFX(SevNoRepIo): + + ; CPUID clobbers ebx, ecx and edx + push rbx + push rcx + push rdx + + ; Check if we are runing under hypervisor + ; CPUID(1).ECX Bit 31 + mov eax, 1 + cpuid + bt ecx, 31 + jnc @UseRepIo + + ; Check if we have Memory encryption CPUID leaf + mov eax, 0x80000000 + cpuid + cmp eax, 0x8000001f + jl @UseRepIo + + ; Check for memory encryption feature: + ; CPUID Fn8000_001F[EAX] - Bit 1 + ; + mov eax, 0x8000001f + cpuid + bt eax, 1 + jnc @UseRepIo + + ; Check if memory encryption is enabled + ; MSR_0xC0010131 - Bit 0 (SEV enabled) + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) + mov ecx, 0xc0010131 + rdmsr + + ; Check for (SevEsEnabled == 0 && SevEnabled == 1) + and eax, 3 + cmp eax, 1 + je @SevNoRepIo_Done + +@UseRepIo: + xor eax, eax + +@SevNoRepIo_Done: + pop rdx + pop rcx + pop rbx + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo8 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; OUT VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo8) +ASM_PFX(IoReadFifo8): + xchg rcx, rdx + xchg rdi, r8 ; rdi: buffer address; r8: save rdi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoReadFifo8_NoRep + + cld + rep insb + jmp @IoReadFifo8_Done + +@IoReadFifo8_NoRep: + jrcxz @IoReadFifo8_Done + +@IoReadFifo8_Loop: + in al, dx + mov byte [rdi], al + inc rdi + loop @IoReadFifo8_Loop + +@IoReadFifo8_Done: + mov rdi, r8 ; restore rdi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo16 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; OUT VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo16) +ASM_PFX(IoReadFifo16): + xchg rcx, rdx + xchg rdi, r8 ; rdi: buffer address; r8: save rdi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoReadFifo16_NoRep + + cld + rep insw + jmp @IoReadFifo16_Done + +@IoReadFifo16_NoRep: + jrcxz @IoReadFifo16_Done + +@IoReadFifo16_Loop: + in ax, dx + mov word [rdi], ax + add rdi, 2 + loop @IoReadFifo16_Loop + +@IoReadFifo16_Done: + mov rdi, r8 ; restore rdi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo32 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; OUT VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoReadFifo32) +ASM_PFX(IoReadFifo32): + xchg rcx, rdx + xchg rdi, r8 ; rdi: buffer address; r8: save rdi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoReadFifo32_NoRep + + cld + rep insd + jmp @IoReadFifo32_Done + +@IoReadFifo32_NoRep: + jrcxz @IoReadFifo32_Done + +@IoReadFifo32_Loop: + in eax, dx + mov dword [rdi], eax + add rdi, 4 + loop @IoReadFifo32_Loop + +@IoReadFifo32_Done: + mov rdi, r8 ; restore rdi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo8 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; IN VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo8) +ASM_PFX(IoWriteFifo8): + xchg rcx, rdx + xchg rsi, r8 ; rsi: buffer address; r8: save rsi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo8_NoRep + + cld + rep outsb + jmp @IoWriteFifo8_Done + +@IoWriteFifo8_NoRep: + jrcxz @IoWriteFifo8_Done + +@IoWriteFifo8_Loop: + mov byte [rsi], al + out dx, al + inc rsi + loop @IoWriteFifo8_Loop + +@IoWriteFifo8_Done: + mov rsi, r8 ; restore rsi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo16 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; IN VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo16) +ASM_PFX(IoWriteFifo16): + xchg rcx, rdx + xchg rsi, r8 ; rsi: buffer address; r8: save rsi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo16_NoRep + + cld + rep outsw + jmp @IoWriteFifo16_Done + +@IoWriteFifo16_NoRep: + jrcxz @IoWriteFifo16_Done + +@IoWriteFifo16_Loop: + mov word [rsi], ax + out dx, ax + add rsi, 2 + loop @IoWriteFifo16_Loop + +@IoWriteFifo16_Done: + mov rsi, r8 ; restore rsi + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoWriteFifo32 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; IN VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(IoWriteFifo32) +ASM_PFX(IoWriteFifo32): + xchg rcx, rdx + xchg rsi, r8 ; rsi: buffer address; r8: save rsi + + call SevNoRepIo ; Check if we need to unroll String I/O + test eax, eax + jnz @IoWriteFifo32_NoRep + + cld + rep outsd + jmp @IoWriteFifo32_Done + +@IoWriteFifo32_NoRep: + jrcxz @IoWriteFifo32_Done + +@IoWriteFifo32_Loop: + mov dword [rsi], eax + out dx, eax + add rsi, 4 + loop @IoWriteFifo32_Loop + +@IoWriteFifo32_Done: + mov rsi, r8 ; restore rsi + ret + diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 2144979..8b69de3 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -134,6 +134,7 @@ [Components.IA32, Components.X64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf -- 2.7.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library 2017-04-06 14:48 ` Leo Duran @ 2017-04-06 14:51 ` Gao, Liming 0 siblings, 0 replies; 3+ messages in thread From: Gao, Liming @ 2017-04-06 14:51 UTC (permalink / raw) To: Leo Duran, edk2-devel@ml01.01.org; +Cc: Kinney, Michael D, Brijesh Singh Reviewed-by: Liming Gao <liming.gao@intel.com> > -----Original Message----- > From: Leo Duran [mailto:leo.duran@amd.com] > Sent: Thursday, April 6, 2017 10:48 PM > To: edk2-devel@ml01.01.org > Cc: Leo Duran <leo.duran@amd.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Brijesh > Singh <brijesh.singh@amd.com> > Subject: [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library > > 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> > --- > .../BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf | 59 +++++ > .../Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm | 293 +++++++++++++++++++++ > .../Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm | 282 ++++++++++++++++++++ > MdePkg/MdePkg.dsc | 1 + > 4 files changed, 635 insertions(+) > create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf > create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm > create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm > > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf > new file mode 100644 > index 0000000..0eec896 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf > @@ -0,0 +1,59 @@ > +## @file > +# Instance of I/O Library using compiler intrinsics. > +# > +# I/O Library that uses compiler intrinsics to perform IN and OUT instructions > +# for IA-32 and x64. > +# > +# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> > +# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> > +# Copyright (c) 2017, AMD Incorporated. 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. > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = BaseIoLibIntrinsicSev > + MODULE_UNI_FILE = BaseIoLibIntrinsic.uni > + FILE_GUID = 93742f95-6e71-4581-b600-8e1da443f95a > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = IoLib > + > + > +# > +# VALID_ARCHITECTURES = IA32 X64 > +# > + > +[Sources] > + IoLibMmioBuffer.c > + BaseIoLibIntrinsicInternal.h > + IoHighLevel.c > + > +[Sources.IA32] > + IoLibGcc.c | GCC > + IoLibMsc.c | MSFT > + IoLibIcc.c | INTEL > + IoLib.c > + Ia32/IoFifoSev.nasm > + > +[Sources.X64] > + IoLibGcc.c | GCC > + IoLibMsc.c | MSFT > + IoLibIcc.c | INTEL > + IoLib.c > + X64/IoFifoSev.nasm > + > +[Packages] > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + DebugLib > + BaseLib > + > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm > new file mode 100644 > index 0000000..9adb972 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifoSev.nasm > @@ -0,0 +1,293 @@ > +;------------------------------------------------------------------------------ > +; > +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> > +; Copyright (c) 2017, AMD Incorporated. 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. > +; > +;------------------------------------------------------------------------------ > + > + SECTION .text > + > +;------------------------------------------------------------------------------ > +; Check whether we need to unroll the String I/O under SEV guest > +; > +; Return // eax (1 - unroll, 0 - no unroll) > +;------------------------------------------------------------------------------ > +global ASM_PFX(SevNoRepIo) > +ASM_PFX(SevNoRepIo): > + > + ; CPUID clobbers ebx, ecx and edx > + push ebx > + push ecx > + push edx > + > + ; Check if we are running under hypervisor > + ; CPUID(1).ECX Bit 31 > + mov eax, 1 > + cpuid > + bt ecx, 31 > + jnc @UseRepIo > + > + ; Check if we have Memory encryption CPUID leaf > + mov eax, 0x80000000 > + cpuid > + cmp eax, 0x8000001f > + jl @UseRepIo > + > + ; Check for memory encryption feature: > + ; CPUID Fn8000_001F[EAX] - Bit 1 > + ; > + mov eax, 0x8000001f > + cpuid > + bt eax, 1 > + jnc @UseRepIo > + > + ; Check if memory encryption is enabled > + ; MSR_0xC0010131 - Bit 0 (SEV enabled) > + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) > + mov ecx, 0xc0010131 > + rdmsr > + > + ; Check for (SevEsEnabled == 0 && SevEnabled == 1) > + and eax, 3 > + cmp eax, 1 > + je @SevNoRepIo_Done > + > +@UseRepIo: > + xor eax, eax > + > +@SevNoRepIo_Done: > + pop edx > + pop ecx > + pop ebx > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo8 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; OUT VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo8) > +ASM_PFX(IoReadFifo8): > + push edi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov edi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll the rep > + test eax, eax > + jnz @IoReadFifo8_NoRep > + > + cld > + rep insb > + jmp @IoReadFifo8_Done > + > +@IoReadFifo8_NoRep: > + jecxz @IoReadFifo8_Done > + > +@IoReadFifo8_Loop: > + in al, dx > + mov byte [edi], al > + inc edi > + loop @IoReadFifo8_Loop > + > +@IoReadFifo8_Done: > + pop edi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo16 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; OUT VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo16) > +ASM_PFX(IoReadFifo16): > + push edi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov edi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll the rep > + test eax, eax > + jnz @IoReadFifo16_NoRep > + > + cld > + rep insw > + jmp @IoReadFifo16_Done > + > +@IoReadFifo16_NoRep: > + jecxz @IoReadFifo16_Done > + > +@IoReadFifo16_Loop: > + in ax, dx > + mov word [edi], ax > + add edi, 2 > + loop @IoReadFifo16_Loop > + > +@IoReadFifo16_Done: > + pop edi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo32 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; OUT VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo32) > +ASM_PFX(IoReadFifo32): > + push edi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov edi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll the rep > + test eax, eax > + jnz @IoReadFifo32_NoRep > + > + cld > + rep insd > + jmp @IoReadFifo32_Done > + > +@IoReadFifo32_NoRep: > + jecxz @IoReadFifo32_Done > + > +@IoReadFifo32_Loop: > + in eax, dx > + mov dword [edi], eax > + add edi, 4 > + loop @IoReadFifo32_Loop > + > +@IoReadFifo32_Done: > + pop edi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo8 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; IN VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo8) > +ASM_PFX(IoWriteFifo8): > + push esi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov esi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo8_NoRep > + > + cld > + rep outsb > + jmp @IoWriteFifo8_Done > + > +@IoWriteFifo8_NoRep: > + jecxz @IoWriteFifo8_Done > + > +@IoWriteFifo8_Loop: > + mov byte [esi], al > + out dx, al > + inc esi > + loop @IoWriteFifo8_Loop > + > +@IoWriteFifo8_Done: > + pop esi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo16 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; IN VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo16) > +ASM_PFX(IoWriteFifo16): > + push esi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov esi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo16_NoRep > + > + cld > + rep outsw > + jmp @IoWriteFifo16_Done > + > +@IoWriteFifo16_NoRep: > + jecxz @IoWriteFifo16_Done > + > +@IoWriteFifo16_Loop: > + mov word [esi], ax > + out dx, ax > + add esi, 2 > + loop @IoWriteFifo16_Loop > + > +@IoWriteFifo16_Done: > + pop esi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo32 ( > +; IN UINTN Port, > +; IN UINTN Size, > +; IN VOID *Buffer > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo32) > +ASM_PFX(IoWriteFifo32): > + push esi > + mov dx, [esp + 8] > + mov ecx, [esp + 12] > + mov esi, [esp + 16] > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo32_NoRep > + > + cld > + rep outsd > + jmp @IoWriteFifo32_Done > + > +@IoWriteFifo32_NoRep: > + jecxz @IoWriteFifo32_Done > + > +@IoWriteFifo32_Loop: > + mov dword [esi], eax > + out dx, eax > + add esi, 4 > + loop @IoWriteFifo32_Loop > + > +@IoWriteFifo32_Done: > + pop esi > + ret > + > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm > new file mode 100644 > index 0000000..20e3e64 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm > @@ -0,0 +1,282 @@ > +;------------------------------------------------------------------------------ > +; > +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> > +; Copyright (c) 2017, AMD Incorporated. 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. > +; > +;------------------------------------------------------------------------------ > + > + DEFAULT REL > + SECTION .text > + > +;------------------------------------------------------------------------------ > +; Check whether we need to unroll the String I/O in SEV guest > +; > +; Return // eax (1 - unroll, 0 - no unroll) > +;------------------------------------------------------------------------------ > +global ASM_PFX(SevNoRepIo) > +ASM_PFX(SevNoRepIo): > + > + ; CPUID clobbers ebx, ecx and edx > + push rbx > + push rcx > + push rdx > + > + ; Check if we are runing under hypervisor > + ; CPUID(1).ECX Bit 31 > + mov eax, 1 > + cpuid > + bt ecx, 31 > + jnc @UseRepIo > + > + ; Check if we have Memory encryption CPUID leaf > + mov eax, 0x80000000 > + cpuid > + cmp eax, 0x8000001f > + jl @UseRepIo > + > + ; Check for memory encryption feature: > + ; CPUID Fn8000_001F[EAX] - Bit 1 > + ; > + mov eax, 0x8000001f > + cpuid > + bt eax, 1 > + jnc @UseRepIo > + > + ; Check if memory encryption is enabled > + ; MSR_0xC0010131 - Bit 0 (SEV enabled) > + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) > + mov ecx, 0xc0010131 > + rdmsr > + > + ; Check for (SevEsEnabled == 0 && SevEnabled == 1) > + and eax, 3 > + cmp eax, 1 > + je @SevNoRepIo_Done > + > +@UseRepIo: > + xor eax, eax > + > +@SevNoRepIo_Done: > + pop rdx > + pop rcx > + pop rbx > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo8 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; OUT VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo8) > +ASM_PFX(IoReadFifo8): > + xchg rcx, rdx > + xchg rdi, r8 ; rdi: buffer address; r8: save rdi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoReadFifo8_NoRep > + > + cld > + rep insb > + jmp @IoReadFifo8_Done > + > +@IoReadFifo8_NoRep: > + jrcxz @IoReadFifo8_Done > + > +@IoReadFifo8_Loop: > + in al, dx > + mov byte [rdi], al > + inc rdi > + loop @IoReadFifo8_Loop > + > +@IoReadFifo8_Done: > + mov rdi, r8 ; restore rdi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo16 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; OUT VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo16) > +ASM_PFX(IoReadFifo16): > + xchg rcx, rdx > + xchg rdi, r8 ; rdi: buffer address; r8: save rdi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoReadFifo16_NoRep > + > + cld > + rep insw > + jmp @IoReadFifo16_Done > + > +@IoReadFifo16_NoRep: > + jrcxz @IoReadFifo16_Done > + > +@IoReadFifo16_Loop: > + in ax, dx > + mov word [rdi], ax > + add rdi, 2 > + loop @IoReadFifo16_Loop > + > +@IoReadFifo16_Done: > + mov rdi, r8 ; restore rdi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoReadFifo32 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; OUT VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoReadFifo32) > +ASM_PFX(IoReadFifo32): > + xchg rcx, rdx > + xchg rdi, r8 ; rdi: buffer address; r8: save rdi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoReadFifo32_NoRep > + > + cld > + rep insd > + jmp @IoReadFifo32_Done > + > +@IoReadFifo32_NoRep: > + jrcxz @IoReadFifo32_Done > + > +@IoReadFifo32_Loop: > + in eax, dx > + mov dword [rdi], eax > + add rdi, 4 > + loop @IoReadFifo32_Loop > + > +@IoReadFifo32_Done: > + mov rdi, r8 ; restore rdi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo8 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; IN VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo8) > +ASM_PFX(IoWriteFifo8): > + xchg rcx, rdx > + xchg rsi, r8 ; rsi: buffer address; r8: save rsi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo8_NoRep > + > + cld > + rep outsb > + jmp @IoWriteFifo8_Done > + > +@IoWriteFifo8_NoRep: > + jrcxz @IoWriteFifo8_Done > + > +@IoWriteFifo8_Loop: > + mov byte [rsi], al > + out dx, al > + inc rsi > + loop @IoWriteFifo8_Loop > + > +@IoWriteFifo8_Done: > + mov rsi, r8 ; restore rsi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo16 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; IN VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo16) > +ASM_PFX(IoWriteFifo16): > + xchg rcx, rdx > + xchg rsi, r8 ; rsi: buffer address; r8: save rsi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo16_NoRep > + > + cld > + rep outsw > + jmp @IoWriteFifo16_Done > + > +@IoWriteFifo16_NoRep: > + jrcxz @IoWriteFifo16_Done > + > +@IoWriteFifo16_Loop: > + mov word [rsi], ax > + out dx, ax > + add rsi, 2 > + loop @IoWriteFifo16_Loop > + > +@IoWriteFifo16_Done: > + mov rsi, r8 ; restore rsi > + ret > + > +;------------------------------------------------------------------------------ > +; VOID > +; EFIAPI > +; IoWriteFifo32 ( > +; IN UINTN Port, // rcx > +; IN UINTN Size, // rdx > +; IN VOID *Buffer // r8 > +; ); > +;------------------------------------------------------------------------------ > +global ASM_PFX(IoWriteFifo32) > +ASM_PFX(IoWriteFifo32): > + xchg rcx, rdx > + xchg rsi, r8 ; rsi: buffer address; r8: save rsi > + > + call SevNoRepIo ; Check if we need to unroll String I/O > + test eax, eax > + jnz @IoWriteFifo32_NoRep > + > + cld > + rep outsd > + jmp @IoWriteFifo32_Done > + > +@IoWriteFifo32_NoRep: > + jrcxz @IoWriteFifo32_Done > + > +@IoWriteFifo32_Loop: > + mov dword [rsi], eax > + out dx, eax > + add rsi, 4 > + loop @IoWriteFifo32_Loop > + > +@IoWriteFifo32_Done: > + mov rsi, r8 ; restore rsi > + ret > + > diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc > index 2144979..8b69de3 100644 > --- a/MdePkg/MdePkg.dsc > +++ b/MdePkg/MdePkg.dsc > @@ -134,6 +134,7 @@ > > [Components.IA32, Components.X64] > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf > + MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf > MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf > MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf > MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf > -- > 2.7.4 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-04-06 14:51 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-04-06 14:48 [PATCH v7] MdePkg: BaseIoLibIntrinsic (IoLib class) library Leo Duran 2017-04-06 14:48 ` Leo Duran 2017-04-06 14:51 ` Gao, Liming
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox