From nobody Mon Feb 9 06:07:49 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+85977+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+85977+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1642901863; cv=none; d=zohomail.com; s=zohoarc; b=dqpPJIZpBTy/utC6a4azq+rSDlOxDWPKR7E3Ipfg/VPAqF5PixEh1oZG6D3/FOTKOTl3eVx8BHH8WDaaI/F0UGb63Dx/1uycBaCe66IcT/Req5hdYAUdNpb2U/mjeCaRRbuxSCJlwpH85J/aubliU/SvoNEVph4IzonWDSGXCTI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1642901863; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=OlXJtXkHFD2Deo3lFWuMoR203BcEhU3moODC5Vanq+Q=; b=NTjdvMjo1dayjy6OVIO14vtubXj3HUlcYnnCrk0LNRtynuywW6kvPrDnHgEPpL1cajqXubRqZPDYp+nO9/ipkCUQgvoSqZD5J7NRv3tM2KY0NPLOYYi8MWnWVjPqc6Pc9RDkh13lfutMWc3Qd1wPnsv8qazUgSZIpZwJRtOpe/c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+85977+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1642901863033824.7484396380988; Sat, 22 Jan 2022 17:37:43 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id JEV7YY1788612xCCCEaHllkP; Sat, 22 Jan 2022 17:37:42 -0800 X-Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web12.4557.1642901847770499599 for ; Sat, 22 Jan 2022 17:37:42 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10235"; a="243454760" X-IronPort-AV: E=Sophos;i="5.88,309,1635231600"; d="scan'208";a="243454760" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2022 17:37:41 -0800 X-IronPort-AV: E=Sophos;i="5.88,309,1635231600"; d="scan'208";a="695032962" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.255.30.84]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2022 17:37:38 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Liming Gao , Zhiguang Liu , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky Subject: [edk2-devel] [PATCH V5 07/33] MdePkg: Add helper functions for Tdx guest in BaseIoLibIntrinsic Date: Sun, 23 Jan 2022 09:36:38 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: Dkgm5p2Tl4uEN0eteryTkeyzx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1642901862; bh=6LkxuQA2bdTi5fIWMZvh80aFR5zm09P1xHF9N2ywFiU=; h=Cc:Date:From:Reply-To:Subject:To; b=wFJkBTZLm04cU5hAEoC552AmynIcIzRk5C55zV6NawztB3kYq4HEvhW7bY1wylkbfAx GPA270UElkm6AgPrLW7VdU6f0Ugzv3z/WhKqkDw/nN+2bDgtF+p0cUoAUILeKX4awsDah YIWrLW/78kolmcTKUCNuQ/CtR+BWzFcxk7o= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1642901864000100001 Content-Type: text/plain; charset="utf-8" RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3429 Intel TDX architecture does not prescribe a specific software convention to perform I/O from the guest TD. Guest TD providers have many choices to provide I/O to the guest. The common I/O models are emulated devices, para-virtualized devices, SRIOV devices and Direct Device assignments. TDVF chooses para-virtualized I/O (Choice-A) which use the TDG.VP.VMCALL function to invoke the funtions provided by the host VMM to perform I/O. Another choice (Choice-B) is the emulation performed by the #VE handler. There are 2 benefits of para-virtualized I/O: 1. Performance. VMEXIT/VMENTRY is skipped so that the performance is better than #VE handler. 2. De-couple with #VE handler. Choice-B depends on the #VE handler which means I/O is not available until #VE handler is installed. For example, in PEI phase #VE handler is installed in CpuMpPei, while communication with Qemu (via I/O port) happen earlier than it. IoLibInternalTdx.c provides the helper functions for Tdx guest. IoLibInternalTdxNull.c provides the null version of the helper functions. It is included in the Non-X64 IoLib so that the build will not be broken. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Signed-off-by: Min Xu --- .../BaseIoLibIntrinsicSev.inf | 2 + .../BaseIoLibIntrinsic/IoLibInternalTdx.c | 675 ++++++++++++++++++ .../BaseIoLibIntrinsic/IoLibInternalTdxNull.c | 497 +++++++++++++ MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h | 410 +++++++++++ 4 files changed, 1584 insertions(+) create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/= MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf index 34f9d1d1062f..336d79736d9a 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf @@ -51,3 +51,5 @@ BaseLib RegisterFilterLib =20 +[LibraryClasses.X64] + TdxLib diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c b/MdePkg/= Library/BaseIoLibIntrinsic/IoLibInternalTdx.c new file mode 100644 index 000000000000..368eea49116a --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c @@ -0,0 +1,675 @@ +/** @file + TDX I/O Library routines. + + Copyright (c) 2020-2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "BaseIoLibIntrinsicInternal.h" +#include +#include +#include +#include +#include +#include "IoLibTdx.h" + +// Size of TDVMCALL Access, including IO and MMIO +#define TDVMCALL_ACCESS_SIZE_1 1 +#define TDVMCALL_ACCESS_SIZE_2 2 +#define TDVMCALL_ACCESS_SIZE_4 4 +#define TDVMCALL_ACCESS_SIZE_8 8 + +// Direction of TDVMCALL Access, including IO and MMIO +#define TDVMCALL_ACCESS_READ 0 +#define TDVMCALL_ACCESS_WRITE 1 + +BOOLEAN mTdxEnabled =3D FALSE; +BOOLEAN mTdxProbed =3D FALSE; + +/** + Check if it is Tdx guest. + + @return TRUE It is Tdx guest + @return FALSE It is not Tdx guest + +**/ +BOOLEAN +EFIAPI +IsTdxGuest ( + VOID + ) +{ + if (mTdxProbed) { + return mTdxEnabled; + } + + mTdxEnabled =3D TdIsEnabled (); + mTdxProbed =3D TRUE; + + return mTdxEnabled; +} + +/** + Reads an 8-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdIoRead8 ( + IN UINTN Port + ) +{ + UINT64 Status; + UINT64 Val; + + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCES= S_READ, Port, 0, &Val); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return (UINT8)Val; +} + +/** + Reads a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdIoRead16 ( + IN UINTN Port + ) +{ + UINT64 Status; + UINT64 Val; + + ASSERT ((Port & 1) =3D=3D 0); + + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCES= S_READ, Port, 0, &Val); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return (UINT16)Val; +} + +/** + Reads a 32-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdIoRead32 ( + IN UINTN Port + ) +{ + UINT64 Status; + UINT64 Val; + + ASSERT ((Port & 3) =3D=3D 0); + + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCES= S_READ, Port, 0, &Val); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return (UINT32)Val; +} + +/** + Writes an 8-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT8 +EFIAPI +TdIoWrite8 ( + IN UINTN Port, + IN UINT8 Value + ) +{ + UINT64 Status; + UINT64 Val; + + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCES= S_WRITE, Port, Val, 0); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return Value; +} + +/** + Writes a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT16 +EFIAPI +TdIoWrite16 ( + IN UINTN Port, + IN UINT16 Value + ) +{ + UINT64 Status; + UINT64 Val; + + ASSERT ((Port & 1) =3D=3D 0); + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCES= S_WRITE, Port, Val, 0); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return Value; +} + +/** + Writes a 32-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT32 +EFIAPI +TdIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + UINT64 Status; + UINT64 Val; + + ASSERT ((Port & 3) =3D=3D 0); + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCES= S_WRITE, Port, Val, 0); + if (Status !=3D 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + + return Value; +} + +/** + Reads an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdMmioRead8 ( + IN UINTN Address + ) +{ + UINT64 Value; + UINT64 Status; + + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACC= ESS_READ, Address | TdSharedPageMask (), 0, &Value); + if (Status !=3D 0) { + Value =3D *(volatile UINT64 *)Address; + } + + return (UINT8)Value; +} + +/** + Writes an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read write registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT8 +EFIAPI +TdMmioWrite8 ( + IN UINTN Address, + IN UINT8 Value + ) +{ + UINT64 Val; + UINT64 Status; + + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACC= ESS_WRITE, Address | TdSharedPageMask (), Val, 0); + if (Status !=3D 0) { + *(volatile UINT8 *)Address =3D Value; + } + + return Value; +} + +/** + Reads a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdMmioRead16 ( + IN UINTN Address + ) +{ + UINT64 Value; + UINT64 Status; + + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACC= ESS_READ, Address | TdSharedPageMask (), 0, &Value); + if (Status !=3D 0) { + Value =3D *(volatile UINT64 *)Address; + } + + return (UINT16)Value; +} + +/** + Writes a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT16 +EFIAPI +TdMmioWrite16 ( + IN UINTN Address, + IN UINT16 Value + ) +{ + UINT64 Val; + UINT64 Status; + + ASSERT ((Address & 1) =3D=3D 0); + + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACC= ESS_WRITE, Address | TdSharedPageMask (), Val, 0); + if (Status !=3D 0) { + *(volatile UINT16 *)Address =3D Value; + } + + return Value; +} + +/** + Reads a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdMmioRead32 ( + IN UINTN Address + ) +{ + UINT64 Value; + UINT64 Status; + + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACC= ESS_READ, Address | TdSharedPageMask (), 0, &Value); + if (Status !=3D 0) { + Value =3D *(volatile UINT64 *)Address; + } + + return (UINT32)Value; +} + +/** + Writes a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT32 +EFIAPI +TdMmioWrite32 ( + IN UINTN Address, + IN UINT32 Value + ) +{ + UINT64 Val; + UINT64 Status; + + ASSERT ((Address & 3) =3D=3D 0); + + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACC= ESS_WRITE, Address | TdSharedPageMask (), Val, 0); + if (Status !=3D 0) { + *(volatile UINT32 *)Address =3D Value; + } + + return Value; +} + +/** + Reads a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +TdMmioRead64 ( + IN UINTN Address + ) +{ + UINT64 Value; + UINT64 Status; + + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_8, TDVMCALL_ACC= ESS_READ, Address | TdSharedPageMask (), 0, &Value); + if (Status !=3D 0) { + Value =3D *(volatile UINT64 *)Address; + } + + return Value; +} + +/** + Writes a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +TdMmioWrite64 ( + IN UINTN Address, + IN UINT64 Value + ) +{ + UINT64 Status; + UINT64 Val; + + ASSERT ((Address & 7) =3D=3D 0); + + Val =3D Value; + Status =3D TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_8, TDVMCALL_ACC= ESS_WRITE, Address | TdSharedPageMask (), Val, 0); + if (Status !=3D 0) { + *(volatile UINT64 *)Address =3D Value; + } + + return Value; +} + +/** + 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(). + + In TDX a serial of TdIoRead8 is invoked to read the I/O port fifo. + + @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 +TdIoReadFifo8 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + UINT8 *Buf8; + UINTN Index; + + Buf8 =3D (UINT8 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + Buf8[Index] =3D TdIoRead8 (Port); + } +} + +/** + 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(). + + In TDX a serial of TdIoWrite8 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo8 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT8 *Buf8; + UINTN Index; + + Buf8 =3D (UINT8 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + TdIoWrite8 (Port, Buf8[Index]); + } +} + +/** + 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(). + + In TDX a serial of TdIoRead16 is invoked to read data from the I/O port. + + @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 +TdIoReadFifo16 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + UINT16 *Buf16; + UINTN Index; + + Buf16 =3D (UINT16 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + Buf16[Index] =3D TdIoRead16 (Port); + } +} + +/** + 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(). + + In TDX a serial of TdIoWrite16 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo16 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT16 *Buf16; + UINTN Index; + + Buf16 =3D (UINT16 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + TdIoWrite16 (Port, Buf16[Index]); + } +} + +/** + 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(). + + In TDX a serial of TdIoRead32 is invoked to read data from the I/O port. + + @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 +TdIoReadFifo32 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + UINT32 *Buf32; + UINTN Index; + + Buf32 =3D (UINT32 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + Buf32[Index] =3D TdIoRead32 (Port); + } +} + +/** + 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(). + + In TDX a serial of TdIoWrite32 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo32 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT32 *Buf32; + UINTN Index; + + Buf32 =3D (UINT32 *)Buffer; + for (Index =3D 0; Index < Count; Index++) { + TdIoWrite32 (Port, Buf32[Index]); + } +} diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c b/Mde= Pkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c new file mode 100644 index 000000000000..7262704d6b14 --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c @@ -0,0 +1,497 @@ +/** @file + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "BaseIoLibIntrinsicInternal.h" +#include "IoLibTdx.h" + +/** + Check if it is Tdx guest. + + @return TRUE It is Tdx guest + @return FALSE It is not Tdx guest + +**/ +BOOLEAN +EFIAPI +IsTdxGuest ( + VOID + ) +{ + return FALSE; +} + +/** + Reads an 8-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdIoRead8 ( + IN UINTN Port + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdIoRead16 ( + IN UINTN Port + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 32-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdIoRead32 ( + IN UINTN Port + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes an 8-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT8 +EFIAPI +TdIoWrite8 ( + IN UINTN Port, + IN UINT8 Value + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT16 +EFIAPI +TdIoWrite16 ( + IN UINTN Port, + IN UINT16 Value + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes a 32-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT32 +EFIAPI +TdIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdMmioRead8 ( + IN UINTN Address + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read write registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT8 +EFIAPI +TdMmioWrite8 ( + IN UINTN Address, + IN UINT8 Val + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdMmioRead16 ( + IN UINTN Address + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT16 +EFIAPI +TdMmioWrite16 ( + IN UINTN Address, + IN UINT16 Val + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdMmioRead32 ( + IN UINTN Address + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT32 +EFIAPI +TdMmioWrite32 ( + IN UINTN Address, + IN UINT32 Val + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +TdMmioRead64 ( + IN UINTN Address + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Writes a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +TdMmioWrite64 ( + IN UINTN Address, + IN UINT64 Value + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + 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(). + + In TDX a serial of TdIoRead8 is invoked to read the I/O port fifo. + + @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 +TdIoReadFifo8 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + ASSERT (FALSE); +} + +/** + 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(). + + In TDX a serial of TdIoWrite8 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo8 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + ASSERT (FALSE); +} + +/** + 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(). + + In TDX a serial of TdIoRead16 is invoked to read data from the I/O port. + + @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 +TdIoReadFifo16 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + ASSERT (FALSE); +} + +/** + 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(). + + In TDX a serial of TdIoWrite16 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo16 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + ASSERT (FALSE); +} + +/** + 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(). + + In TDX a serial of TdIoRead32 is invoked to read data from the I/O port. + + @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 +TdIoReadFifo32 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + ASSERT (FALSE); +} + +/** + 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(). + + In TDX a serial of TdIoWrite32 is invoked to write data to the I/O port. + + @param Port The I/O port to write. + @param Count The number of times to write I/O port. + @param Buffer The buffer to retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo32 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + ASSERT (FALSE); +} diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h b/MdePkg/Library/= BaseIoLibIntrinsic/IoLibTdx.h new file mode 100644 index 000000000000..ab2fa771f6c8 --- /dev/null +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h @@ -0,0 +1,410 @@ +/** @file + Header file for Tdx IO library. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef IOLIB_TDX_H_ +#define IOLIB_TDX_H_ + +/** + Check if it is Tdx guest. + + @return TRUE It is Tdx guest + @return FALSE It is not Tdx guest + +**/ +BOOLEAN +EFIAPI +IsTdxGuest ( + VOID + ); + +/** + Reads an 8-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdIoRead8 ( + IN UINTN Port + ); + +/** + Reads a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdIoRead16 ( + IN UINTN Port + ); + +/** + Reads a 32-bit I/O port. + + TDVMCALL_IO is invoked to read I/O port. + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdIoRead32 ( + IN UINTN Port + ); + +/** + Writes an 8-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT8 +EFIAPI +TdIoWrite8 ( + IN UINTN Port, + IN UINT8 Value + ); + +/** + Writes a 16-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT16 +EFIAPI +TdIoWrite16 ( + IN UINTN Port, + IN UINT16 Value + ); + +/** + Writes a 32-bit I/O port. + + TDVMCALL_IO is invoked to write I/O port. + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT32 +EFIAPI +TdIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ); + +/** + Reads an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +TdMmioRead8 ( + IN UINTN Address + ); + +/** + Writes an 8-bit MMIO register. + + TDVMCALL_MMIO is invoked to read write registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT8 +EFIAPI +TdMmioWrite8 ( + IN UINTN Address, + IN UINT8 Val + ); + +/** + Reads a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +TdMmioRead16 ( + IN UINTN Address + ); + +/** + Writes a 16-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT16 +EFIAPI +TdMmioWrite16 ( + IN UINTN Address, + IN UINT16 Val + ); + +/** + Reads a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +TdMmioRead32 ( + IN UINTN Address + ); + +/** + Writes a 32-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT32 +EFIAPI +TdMmioWrite32 ( + IN UINTN Address, + IN UINT32 Val + ); + +/** + Reads a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to read MMIO registers. + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +TdMmioRead64 ( + IN UINTN Address + ); + +/** + Writes a 64-bit MMIO register. + + TDVMCALL_MMIO is invoked to write MMIO registers. + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +TdMmioWrite64 ( + IN UINTN Address, + IN UINT64 Value + ); + +/** + Reads an 8-bit I/O port fifo into a block of memory in Tdx. + + 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 +TdIoReadFifo8 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Writes a block of memory into an 8-bit I/O port fifo in Tdx. + + 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 retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo8 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ); + +/** + Reads a 16-bit I/O port fifo into a block of memory in Tdx. + + 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 +TdIoReadFifo16 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Writes a block of memory into a 16-bit I/O port fifo in Tdx. + + 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 retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo16 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ); + +/** + Reads a 32-bit I/O port fifo into a block of memory in Tdx. + + 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 +TdIoReadFifo32 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Writes a block of memory into a 32-bit I/O port fifo in Tdx. + + 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 retrieve the write data from. + +**/ +VOID +EFIAPI +TdIoWriteFifo32 ( + IN UINTN Port, + IN UINTN Count, + IN VOID *Buffer + ); + +#endif --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#85977): https://edk2.groups.io/g/devel/message/85977 Mute This Topic: https://groups.io/mt/88617498/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-