Hi
Would you please try to merge TdxLib and TdxLibSec?
I am not sure if we really need two instance.

Also, can we remove MemoryAllocationLib ? 
If it is just used to allocate aligned memory, can we allocate aligned memory 
in stack instead of heap ?



> -----Original Message-----
> From: Xu, Min M <min.m...@intel.com>
> Sent: Tuesday, March 9, 2021 2:13 PM
> To: devel@edk2.groups.io
> Cc: Xu, Min M <min.m...@intel.com>; Justen, Jordan L
> <jordan.l.jus...@intel.com>; Laszlo Ersek <ler...@redhat.com>; Yao, Jiewen
> <jiewen....@intel.com>; Reiland, Doug <doug.reil...@intel.com>
> Subject: [PATCH V3 3/3] OvmfPkg: Implement library support for TdxLib SEC and
> DXE on OVMF
> 
> The base TdxLib in MdePkg/Library provides a default limited interface.
> As it does not provide full support, create an OVMF version of this library
> to begin the process of providing full support of TDX in OVMF.
> 
> Cc: Jordan Justen <jordan.l.jus...@intel.com>
> Cc: Laszlo Ersek <ler...@redhat.com>
> Cc: Jiewen Yao <jiewen....@intel.com>
> 
> Signed-off-by: Min Xu <min.m...@intel.com>
> Signed-off-by: Doug Reiland <doug.reil...@intel.com>
> ---
>  OvmfPkg/Library/TdxLib/AcceptPages.c     |  68 ++++++++
>  OvmfPkg/Library/TdxLib/Rtmr.c            |  80 +++++++++
>  OvmfPkg/Library/TdxLib/TdReport.c        | 102 +++++++++++
>  OvmfPkg/Library/TdxLib/TdxLib.inf        |  48 ++++++
>  OvmfPkg/Library/TdxLib/TdxLibSec.inf     |  45 +++++
>  OvmfPkg/Library/TdxLib/X64/Tdcall.nasm   | 125 ++++++++++++++
>  OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm | 211 +++++++++++++++++++++++
>  7 files changed, 679 insertions(+)
>  create mode 100644 OvmfPkg/Library/TdxLib/AcceptPages.c
>  create mode 100644 OvmfPkg/Library/TdxLib/Rtmr.c
>  create mode 100644 OvmfPkg/Library/TdxLib/TdReport.c
>  create mode 100644 OvmfPkg/Library/TdxLib/TdxLib.inf
>  create mode 100644 OvmfPkg/Library/TdxLib/TdxLibSec.inf
>  create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
>  create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
> 
> diff --git a/OvmfPkg/Library/TdxLib/AcceptPages.c
> b/OvmfPkg/Library/TdxLib/AcceptPages.c
> new file mode 100644
> index 000000000000..3848bb6a95a4
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/AcceptPages.c
> @@ -0,0 +1,68 @@
> +/** @file
> +
> +  There are 4 defined types in TD memory.
> +  Unaccepted memory is a special type of private memory. The OVMF must
> +  invoke TDCALL [TDG.MEM.PAGE.ACCEPT] the unaccepted memory before use
> it.
> +
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <IndustryStandard/Tdx.h>
> +#include <Library/TdxLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +UINT64  mNumberOfDuplicatedAcceptedPages;
> +
> +/**
> +  This function accept a pending private page, and initialize the page to
> +  all-0 using the TD ephemeral private key.
> +
> +  @param[in]  StartAddress           Guest physical address of the private
> +                                     page to accept.
> +  @param[in]  NumberOfPages          Number of the pages to be accepted.
> +
> +  @return EFI_SUCCESS
> +**/
> +EFI_STATUS
> +EFIAPI
> +TdAcceptPages (
> +  IN UINT64  StartAddress,
> +  IN UINT64  NumberOfPages
> +  )
> +{
> +  UINT64  Address;
> +  UINT64  Status;
> +  UINT64  Index;
> +
> +  //
> +  // Determine if we need to accept pages before use
> +  //
> +  if (FixedPcdGetBool(PcdUseTdxAcceptPage) == FALSE) {
> +     return EFI_SUCCESS;
> +  }
> +
> +  Address = StartAddress;
> +
> +  for( Index = 0; Index < NumberOfPages; Index++) {
> +    Status = TdCall(TDCALL_TDACCEPTPAGE,Address, 0, 0, 0);
> +    if (Status != TDX_EXIT_REASON_SUCCESS) {
> +        if ((Status & ~0xFFULL) == TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED)
> {
> +          ++mNumberOfDuplicatedAcceptedPages;
> +          DEBUG((DEBUG_VERBOSE, "Address %llx already accepted. Total number
> of already accepted pages %ld\n",
> +            Address, mNumberOfDuplicatedAcceptedPages));
> +        } else {
> +          DEBUG((DEBUG_ERROR, "Address %llx failed to be accepted. Error
> = %ld\n",
> +            Address, Status));
> +          ASSERT(Status == TDX_EXIT_REASON_SUCCESS);
> +        }
> +    }
> +    Address += EFI_PAGE_SIZE;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/OvmfPkg/Library/TdxLib/Rtmr.c b/OvmfPkg/Library/TdxLib/Rtmr.c
> new file mode 100644
> index 000000000000..a4b36b6c4bef
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/Rtmr.c
> @@ -0,0 +1,80 @@
> +/** @file
> +
> +  Extends one of the RTMR measurement registers in TDCS with the provided
> +  extension data in memory.
> +
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/TdxLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Tpm20.h>
> +#include <IndustryStandard/Tdx.h>
> +#include <Protocol/Tdx.h>
> +
> +#define RTMR_COUNT  4
> +
> +/**
> +  This function extends one of the RTMR measurement register
> +  in TDCS with the provided extension data in memory.
> +  RTMR extending supports SHA384 which length is 48 bytes.
> +
> +  @param[in]  Data      Point to the data to be extended
> +  @param[in]  DataLen   Length of the data. Must be 48
> +  @param[in]  Index     RTMR index
> +
> +  @return EFI_SUCCESS
> +  @return EFI_INVALID_PARAMETER
> +  @return EFI_DEVICE_ERROR
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TdExtendRtmr(
> +  IN  UINT32  *Data,
> +  IN  UINT32  DataLen,
> +  IN  UINT8   Index
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINT64                *Buffer;
> +  UINT64                TdCallStatus;
> +
> +  Status = EFI_SUCCESS;
> +
> +  ASSERT(Index >= 0 && Index < RTMR_COUNT);
> +  ASSERT(DataLen == SHA384_DIGEST_SIZE);
> +
> +  //
> +  // Allocate 64B aligned mem to hold the sha384 hash value
> +  //
> +  Buffer = AllocateAlignedPages(EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE), 64);
> +  if(Data == NULL){
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyMem(Buffer, Data, SHA384_DIGEST_SIZE);
> +
> +  TdCallStatus = TdCall(TDCALL_TDEXTENDRTMR, (UINT64)Buffer, Index, 0, 0);
> +
> +  if(TdCallStatus == TDX_EXIT_REASON_SUCCESS){
> +    Status = EFI_SUCCESS;
> +  }else if(TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID){
> +    Status = EFI_INVALID_PARAMETER;
> +  }else{
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  if(Status != EFI_SUCCESS){
> +    DEBUG((DEBUG_ERROR, "Error returned from TdExtendRtmr call - 0x%lx\n",
> TdCallStatus));
> +  }
> +
> +  FreeAlignedPages(Buffer, EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE));
> +
> +  return Status;
> +}
> diff --git a/OvmfPkg/Library/TdxLib/TdReport.c
> b/OvmfPkg/Library/TdxLib/TdReport.c
> new file mode 100644
> index 000000000000..ace213bcf467
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/TdReport.c
> @@ -0,0 +1,102 @@
> +/** @file
> +
> +  Retrieve TDREPORT_STRUCT structure from TDX
> +
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Tdx.h>
> +#include <Library/TdxLib.h>
> +
> +#define REPORT_STRUCT_SIZE    1024
> +#define ADDITIONAL_DATA_SIZE  64
> +
> +/**
> +  This function retrieve TDREPORT_STRUCT structure from TDX.
> +  The struct contains the measurements/configuration information of
> +  the guest TD that called the function, measurements/configuratio
> +  information of the TDX-SEAM module and a REPORTMACSTRUCT.
> +  The REPORTMACSTRUCT is integrity protected with a MAC and
> +  contains the hash of the measurements and configuration
> +  as well as additional REPORTDATA provided by the TD software.
> +
> +  AdditionalData, a 64-byte value, is provided by the guest TD
> +  to be included in the TDREPORT
> +
> +  @param[in,out]  Report             Holds the TEREPORT_STRUCT.
> +  @param[in]      ReportSize         Size of the report. It must be
> +                                     larger than 1024B.
> +  @param[in]      AdditionalData     Point to the additional data.
> +  @param[in]      AdditionalDataSize Size of the additional data.
> +                                     If AdditionalData != NULL, then
> +                                     this value must be 64B.
> +
> +  @return EFI_SUCCESS
> +  @return EFI_INVALID_PARAMETER
> +  @return EFI_DEVICE_ERROR
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TdReport(
> +  IN OUT UINT8  *Report,
> +  IN  UINT32    ReportSize,
> +  IN  UINT8     *AdditionalData,
> +  IN  UINT32    AdditionalDataSize
> +  )
> +
> +{
> +  EFI_STATUS  Status;
> +  UINT64      *Data;
> +  UINT64      *Report_Struct;
> +  UINT64      *Report_Data;
> +  UINT64      TdCallStatus;
> +
> +  if(ReportSize < REPORT_STRUCT_SIZE){
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if(AdditionalData != NULL && AdditionalDataSize != ADDITIONAL_DATA_SIZE){
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Data = AllocatePages(EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE +
> ADDITIONAL_DATA_SIZE));
> +  if(Data == NULL){
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Report_Struct = Data;
> +  Report_Data = Data + REPORT_STRUCT_SIZE;
> +  if(AdditionalData != NULL){
> +    CopyMem(Report_Data, AdditionalData, ADDITIONAL_DATA_SIZE);
> +  }else{
> +    ZeroMem(Report_Data, ADDITIONAL_DATA_SIZE);
> +  }
> +
> +  TdCallStatus = TdCall(TDCALL_TDREPORT, (UINT64)Report_Struct,
> (UINT64)Report_Data, 0, 0);
> +
> +  if(TdCallStatus == TDX_EXIT_REASON_SUCCESS){
> +    Status = EFI_SUCCESS;
> +  }else if(TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID){
> +    Status = EFI_INVALID_PARAMETER;
> +  }else{
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  if(Status != EFI_SUCCESS){
> +    DEBUG((DEBUG_ERROR, "Error returned from TdReport call - 0x%lx\n",
> TdCallStatus));
> +  }else{
> +    CopyMem(Report, Data, REPORT_STRUCT_SIZE);
> +  }
> +
> +  FreePages(Data, EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE +
> ADDITIONAL_DATA_SIZE));
> +
> +  return Status;
> +}
> diff --git a/OvmfPkg/Library/TdxLib/TdxLib.inf
> b/OvmfPkg/Library/TdxLib/TdxLib.inf
> new file mode 100644
> index 000000000000..f642de9e3a5f
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/TdxLib.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Tdx library
> +#
> +# Copyright (c) 2020- 2021, 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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = TdxLib
> +  FILE_GUID                      = 032A8E0D-0C27-40C0-9CAA-23B731C1B223
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = TdxLib|PEI_CORE PEIM DXE_CORE DXE_DRIVER
> DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
> +
> +#
> +# The following information is for reference only and not required by the 
> build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = X64
> +#
> +
> +[Sources]
> +  Rtmr.c
> +  TdReport.c
> +  AcceptPages.c
> +  X64/Tdcall.nasm
> +  X64/Tdvmcall.nasm
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage
> +  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation
> diff --git a/OvmfPkg/Library/TdxLib/TdxLibSec.inf
> b/OvmfPkg/Library/TdxLib/TdxLibSec.inf
> new file mode 100644
> index 000000000000..82ef4f08be8c
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/TdxLibSec.inf
> @@ -0,0 +1,45 @@
> +## @file
> +# Tdx library for SEC phase.
> +#
> +# Copyright (c) 2020 - 2021, 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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = TdxLibSec
> +  FILE_GUID                      = 498E8E1E-5B11-41F3-9083-EEE3A32B009D
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = TdxLib|SEC
> +
> +#
> +# The following information is for reference only and not required by the 
> build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = X64
> +#
> +
> +[Sources]
> +  AcceptPages.c
> +  X64/Tdcall.nasm
> +  X64/Tdvmcall.nasm
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage
> +  gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation
> diff --git a/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
> b/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
> new file mode 100644
> index 000000000000..d0d55e2a9443
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm
> @@ -0,0 +1,125 @@
> +;------------------------------------------------------------------------------
> +;*
> +;*   Copyright (c) 2020, 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.
> +;*
> +;*
> +;------------------------------------------------------------------------------
> +
> +DEFAULT REL
> +SECTION .text
> +
> +%macro tdcall 0
> +%if (FixedPcdGet32 (PcdUseTdxEmulation) != 0)
> +    vmcall
> +%else
> +    db 0x66,0x0f,0x01,0xcc
> +%endif
> +%endmacro
> +
> +%macro tdcall_push_regs 0
> +    push rbp
> +    mov  rbp, rsp
> +    push r15
> +    push r14
> +    push r13
> +    push r12
> +    push rbx
> +    push rsi
> +    push rdi
> +%endmacro
> +
> +%macro tdcall_pop_regs 0
> +    pop rdi
> +    pop rsi
> +    pop rbx
> +    pop r12
> +    pop r13
> +    pop r14
> +    pop r15
> +    pop rbp
> +%endmacro
> +
> +%define number_of_regs_pushed 8
> +%define number_of_parameters  4
> +
> +; Keep these in sync for push_regs/pop_regs, code below uses them to find 5th
> or greater parameters
> +%define first_variable_on_stack_offset  (number_of_regs_pushed * 8) +
> (number_of_parameters * 8) + 8
> +%define second_variable_on_stack_offset (first_variable_on_stack_offset) + 8
> +
> +%macro tdcall_regs_preamble 2
> +    mov rax, %1
> +
> +    mov ecx, %2
> +
> +    ; R10 = 0 (standard TDVMCALL)
> +
> +    xor r10d, r10d
> +
> +    ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
> +    ; secrets to the VMM.
> +
> +    xor ebx, ebx
> +    xor esi, esi
> +    xor edi, edi
> +
> +    xor edx, edx
> +    xor ebp, ebp
> +    xor r8d, r8d
> +    xor r9d, r9d
> +%endmacro
> +
> +%macro tdcall_regs_postamble 0
> +    xor ebx, ebx
> +    xor esi, esi
> +    xor edi, edi
> +
> +    xor ecx, ecx
> +    xor edx, edx
> +    xor r8d,  r8d
> +    xor r9d,  r9d
> +    xor r10d, r10d
> +    xor r11d, r11d
> +%endmacro
> +
> +;  TdCall (
> +;    UINT64  Leaf,  // Rcx
> +;    UINT64  P1,  // Rdx
> +;    UINT64  P2,  // R8
> +;    UINT64  P3,  // R9
> +;    UINT64  Results,  // rsp + 0x28
> +;    )
> +global ASM_PFX(TdCall)
> +ASM_PFX(TdCall):
> +       tdcall_push_regs
> +
> +       mov rax, rcx
> +       mov rcx, rdx
> +       mov rdx, r8
> +       mov r8, r9
> +
> +       tdcall
> +
> +       ; exit if tdcall reports failure.
> +       test rax, rax
> +       jnz .exit
> +
> +       ; test if caller wanted results
> +       mov r12, [rsp + first_variable_on_stack_offset ]
> +       test r12, r12
> +       jz .exit
> +       mov [r12 + 0 ], rcx
> +       mov [r12 + 8 ], rdx
> +       mov [r12 + 16], r8
> +       mov [r12 + 24], r9
> +       mov [r12 + 32], r10
> +       mov [r12 + 40], r11
> +.exit:
> +       tdcall_pop_regs
> +       ret
> diff --git a/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
> b/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
> new file mode 100644
> index 000000000000..e1da9b4fbdd6
> --- /dev/null
> +++ b/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm
> @@ -0,0 +1,211 @@
> +;------------------------------------------------------------------------------
> +;*
> +;*   Copyright (c) 2020, 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.
> +;*
> +;*
> +;------------------------------------------------------------------------------
> +
> +DEFAULT REL
> +SECTION .text
> +
> +%define TDVMCALL_EXPOSE_REGS_MASK       0xffec
> +%define TDVMCALL                        0x0
> +%define EXIT_REASON_CPUID               0xa
> +
> +%macro tdcall 0
> +%if (FixedPcdGet32 (PcdUseTdxEmulation) != 0)
> +    vmcall
> +%else
> +    db 0x66,0x0f,0x01,0xcc
> +%endif
> +%endmacro
> +
> +%macro tdcall_push_regs 0
> +    push rbp
> +    mov  rbp, rsp
> +    push r15
> +    push r14
> +    push r13
> +    push r12
> +    push rbx
> +    push rsi
> +    push rdi
> +%endmacro
> +
> +%macro tdcall_pop_regs 0
> +    pop rdi
> +    pop rsi
> +    pop rbx
> +    pop r12
> +    pop r13
> +    pop r14
> +    pop r15
> +    pop rbp
> +%endmacro
> +
> +%define number_of_regs_pushed 8
> +%define number_of_parameters  4
> +
> +; Keep these in sync for push_regs/pop_regs, code below uses them to find 5th
> or greater parameters
> +%define first_variable_on_stack_offset  (number_of_regs_pushed * 8) +
> (number_of_parameters * 8) + 8
> +%define second_variable_on_stack_offset (first_variable_on_stack_offset) + 8
> +
> +%macro tdcall_regs_preamble 2
> +    mov rax, %1
> +
> +    mov ecx, %2
> +
> +    ; R10 = 0 (standard TDVMCALL)
> +
> +    xor r10d, r10d
> +
> +    ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
> +    ; secrets to the VMM.
> +
> +    xor ebx, ebx
> +    xor esi, esi
> +    xor edi, edi
> +
> +    xor edx, edx
> +    xor ebp, ebp
> +    xor r8d, r8d
> +    xor r9d, r9d
> +%endmacro
> +
> +%macro tdcall_regs_postamble 0
> +    xor ebx, ebx
> +    xor esi, esi
> +    xor edi, edi
> +
> +    xor ecx, ecx
> +    xor edx, edx
> +    xor r8d,  r8d
> +    xor r9d,  r9d
> +    xor r10d, r10d
> +    xor r11d, r11d
> +%endmacro
> +
> +;------------------------------------------------------------------------------
> +; 0   => RAX = TDCALL leaf
> +; M   => RCX = TDVMCALL register behavior
> +; 1   => R10 = standard vs. vendor
> +; RDI => R11 = TDVMCALL function / nr
> +; RSI =  R12 = p1
> +; RDX => R13 = p2
> +; RCX => R14 = p3
> +; R8  => R15 = p4
> +
> +;  UINT64
> +;  EFIAPI
> +;  TdVmCall (
> +;    UINT64  Leaf,  // Rcx
> +;    UINT64  P1,  // Rdx
> +;    UINT64  P2,  // R8
> +;    UINT64  P3,  // R9
> +;    UINT64  P4,  // rsp + 0x28
> +;    UINT64  *Val // rsp + 0x30
> +;    )
> +global ASM_PFX(TdVmCall)
> +ASM_PFX(TdVmCall):
> +       tdcall_push_regs
> +
> +       mov r11, rcx
> +       mov r12, rdx
> +       mov r13, r8
> +       mov r14, r9
> +       mov r15, [rsp + first_variable_on_stack_offset ]
> +
> +       tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
> +
> +       tdcall
> +
> +       ; ignore return dataif TDCALL reports failure.
> +       test rax, rax
> +       jnz .no_return_data
> +
> +       ; Propagate TDVMCALL success/failure to return value.
> +       mov rax, r10
> +
> +       ; Retrieve the Val pointer.
> +       mov r9, [rsp + second_variable_on_stack_offset ]
> +       test r9, r9
> +       jz .no_return_data
> +
> +       ; On success, propagate TDVMCALL output value to output param
> +       test rax, rax
> +       jnz .no_return_data
> +       mov [r9], r11
> +.no_return_data:
> +       tdcall_regs_postamble
> +
> +       tdcall_pop_regs
> +
> +       ret
> +
> +;------------------------------------------------------------------------------
> +; 0   => RAX = TDCALL leaf
> +; M   => RCX = TDVMCALL register behavior
> +; 1   => R10 = standard vs. vendor
> +; RDI => R11 = TDVMCALL function / nr
> +; RSI =  R12 = p1
> +; RDX => R13 = p2
> +; RCX => R14 = p3
> +; R8  => R15 = p4
> +
> +;  UINT64
> +;  EFIAPI
> +;  TdVmCallCpuid (
> +;    UINT64  EaxIn,  // Rcx
> +;    UINT64  EcxIn,  // Rdx
> +;    UINT64  *Results  // R8
> +;    )
> +global ASM_PFX(TdVmCallCpuid)
> +ASM_PFX(TdVmCallCpuid):
> +       tdcall_push_regs
> +
> +       mov r11, EXIT_REASON_CPUID
> +       mov r12, rcx
> +       mov r13, rdx
> +
> +       tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
> +
> +       ; Save *results pointers
> +       push r8
> +
> +       tdcall
> +
> +       ; Panic if TDCALL reports failure.
> +       test rax, rax
> +       jnz .no_return_data
> +
> +       ; Propagate TDVMCALL success/failure to return value.
> +       mov rax, r10
> +       test rax, rax
> +       jnz .no_return_data
> +
> +       ; Retrieve *Results
> +       pop r8
> +       test r8, r8
> +       jnz .no_return_data
> +       ; Caller pass in buffer so store results r12-r15 contains eax-edx
> +       mov [r8 +  0], r12
> +       mov [r8 +  8], r13
> +       mov [r8 + 16], r14
> +       mov [r8 + 24], r15
> +
> +.no_return_data:
> +       tdcall_regs_postamble
> +
> +       tdcall_pop_regs
> +
> +       ret
> +
> +.panic:
> +       ud2
> --
> 2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72572): https://edk2.groups.io/g/devel/message/72572
Mute This Topic: https://groups.io/mt/81195559/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to