From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min Xu <min.m.xu@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Zhiguang Liu <zhiguang.liu@intel.com>,
Brijesh Singh <brijesh.singh@amd.com>,
Erdem Aktas <erdemaktas@google.com>,
James Bottomley <jejb@linux.ibm.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Tom Lendacky <thomas.lendacky@amd.com>
Subject: [PATCH V2 06/28] MdePkg: Update BaseIoLibIntrinsicSev to support Tdx
Date: Tue, 5 Oct 2021 11:39:17 +0800 [thread overview]
Message-ID: <78bc0164be0e6adb1edf4454bdc3aaf1d55a2771.1633401643.git.min.m.xu@intel.com> (raw)
In-Reply-To: <cover.1633401643.git.min.m.xu@intel.com>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429
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.
BaseIoLibIntrinsicSev.inf is the IoLib used by OvmfPkg. TDVF updates
BaseIoLibIntrinsicSev to support I/O in Td guest. Below files are updated
to support I/O in Td guest.
- IoLib.c
- IoLibGcc.c
- IoLibMsc.c
- X64/IoFifoSev.nasm
In the I/O functions of above files, if IsTdxGuest() returns TRUE, then
Td I/O routine is called, otherwise the legacy I/O routine is called.
Td I/O routines are declared in IoLibTdx.h and implemented in
IoLibInternalTdx.c.
BaseIoLibIntrinsic.inf is the IoLib used by other packages. It will not
support I/O in Td guest. But some files are shared between
BaseIoLibIntrinsic and BaseIoLibIntrinsicSev (IoLib.c is the example). So
IoLibInternalTdxNull.c is created which holds the null stub of the Td I/O
routines. IoLibInternalTdxNull.c is included in BaseIoLibIntrinsic.inf.
BaseIoLibIntrinsic.inf doesn't import TdxLib so that the Pkgs which
include BaseIoLibIntrinsic.inf need not include TdxLib.
BaseIoLibIntrinsicArmVirt.inf is not touched because it shares no files
with BaseIoLibIntrinsicSev.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
.../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | 2 +
.../BaseIoLibIntrinsicSev.inf | 7 +-
MdePkg/Library/BaseIoLibIntrinsic/IoLib.c | 97 ++-
MdePkg/Library/BaseIoLibIntrinsic/IoLibFifo.c | 216 +++++
MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c | 49 +-
.../BaseIoLibIntrinsic/IoLibInternalTdx.c | 735 ++++++++++++++++++
.../BaseIoLibIntrinsic/IoLibInternalTdxNull.c | 499 ++++++++++++
MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c | 73 +-
MdePkg/Library/BaseIoLibIntrinsic/IoLibSev.h | 166 ++++
MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h | 411 ++++++++++
.../BaseIoLibIntrinsic/X64/IoFifoSev.nasm | 34 +-
11 files changed, 2223 insertions(+), 66 deletions(-)
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibFifo.c
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibSev.h
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
index 97eeada0656e..27b15d9ae256 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
@@ -34,6 +34,8 @@
IoLibMmioBuffer.c
BaseIoLibIntrinsicInternal.h
IoHighLevel.c
+ IoLibInternalTdxNull.c
+ IoLibTdx.h
[Sources.IA32]
IoLibGcc.c | GCC
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
index 34f9d1d1062f..7e94be5a794f 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
@@ -30,17 +30,22 @@
IoLibMmioBuffer.c
BaseIoLibIntrinsicInternal.h
IoHighLevel.c
+ IoLibSev.h
+ IoLibTdx.h
[Sources.IA32]
IoLibGcc.c | GCC
IoLibMsc.c | MSFT
IoLib.c
+ IoLibInternalTdxNull.c
Ia32/IoFifoSev.nasm
[Sources.X64]
IoLibGcc.c | GCC
IoLibMsc.c | MSFT
IoLib.c
+ IoLibFifo.c
+ IoLibInternalTdx.c
X64/IoFifoSev.nasm
[Packages]
@@ -50,4 +55,4 @@
DebugLib
BaseLib
RegisterFilterLib
-
+ TdxLib
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
index d0d7044f0901..68298749ee56 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
@@ -7,6 +7,7 @@
**/
#include "BaseIoLibIntrinsicInternal.h"
+#include "IoLibTdx.h"
/**
Reads a 64-bit I/O port.
@@ -70,6 +71,8 @@ IoWrite64 (
If 8-bit MMIO register operations are not supported, then ASSERT().
+ For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
@param Address The MMIO register to read.
@return The value read.
@@ -86,9 +89,13 @@ MmioRead8 (
Flag = FilterBeforeMmIoRead (FilterWidth8, Address, &Value);
if (Flag) {
- MemoryFence ();
- Value = *(volatile UINT8*)Address;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ Value = TdMmioRead8 (Address);
+ } else {
+ MemoryFence ();
+ Value = *(volatile UINT8*)Address;
+ MemoryFence ();
+ }
}
FilterAfterMmIoRead (FilterWidth8, Address, &Value);
@@ -104,6 +111,8 @@ MmioRead8 (
If 8-bit MMIO register operations are not supported, then ASSERT().
+ For Td guest 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.
@@ -121,9 +130,13 @@ MmioWrite8 (
Flag = FilterBeforeMmIoWrite (FilterWidth8, Address, &Value);
if (Flag) {
- MemoryFence ();
- *(volatile UINT8*)Address = Value;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ TdMmioWrite8 (Address, Value);
+ } else {
+ MemoryFence ();
+ *(volatile UINT8*)Address = Value;
+ MemoryFence ();
+ }
}
FilterAfterMmIoWrite (FilterWidth8, Address, &Value);
@@ -140,6 +153,8 @@ MmioWrite8 (
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
@param Address The MMIO register to read.
@return The value read.
@@ -157,9 +172,13 @@ MmioRead16 (
ASSERT ((Address & 1) == 0);
Flag = FilterBeforeMmIoRead (FilterWidth16, Address, &Value);
if (Flag) {
- MemoryFence ();
- Value = *(volatile UINT16*)Address;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ Value = TdMmioRead16 (Address);
+ } else {
+ MemoryFence ();
+ Value = *(volatile UINT16*)Address;
+ MemoryFence ();
+ }
}
FilterAfterMmIoRead (FilterWidth16, Address, &Value);
@@ -176,6 +195,8 @@ MmioRead16 (
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -195,9 +216,13 @@ MmioWrite16 (
Flag = FilterBeforeMmIoWrite (FilterWidth16, Address, &Value);
if (Flag) {
- MemoryFence ();
- *(volatile UINT16*)Address = Value;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ TdMmioWrite16 (Address, Value);
+ } else {
+ MemoryFence ();
+ *(volatile UINT16*)Address = Value;
+ MemoryFence ();
+ }
}
FilterAfterMmIoWrite (FilterWidth16, Address, &Value);
@@ -214,6 +239,8 @@ MmioWrite16 (
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
@param Address The MMIO register to read.
@return The value read.
@@ -232,9 +259,13 @@ MmioRead32 (
Flag = FilterBeforeMmIoRead (FilterWidth32, Address, &Value);
if (Flag) {
- MemoryFence ();
- Value = *(volatile UINT32*)Address;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ Value = TdMmioRead32 (Address);
+ } else {
+ MemoryFence ();
+ Value = *(volatile UINT32*)Address;
+ MemoryFence ();
+ }
}
FilterAfterMmIoRead (FilterWidth32, Address, &Value);
@@ -251,6 +282,8 @@ MmioRead32 (
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -270,9 +303,13 @@ MmioWrite32 (
Flag = FilterBeforeMmIoWrite (FilterWidth32, Address, &Value);
if (Flag) {
- MemoryFence ();
- *(volatile UINT32*)Address = Value;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ TdMmioWrite32 (Address, Value);
+ } else {
+ MemoryFence ();
+ *(volatile UINT32*)Address = Value;
+ MemoryFence ();
+ }
}
FilterAfterMmIoWrite (FilterWidth32, Address, &Value);
@@ -289,6 +326,8 @@ MmioWrite32 (
If 64-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 64-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
@param Address The MMIO register to read.
@return The value read.
@@ -307,9 +346,13 @@ MmioRead64 (
Flag = FilterBeforeMmIoRead (FilterWidth64, Address, &Value);
if (Flag) {
- MemoryFence ();
- Value = *(volatile UINT64*)Address;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ Value = TdMmioRead64 (Address);
+ } else {
+ MemoryFence ();
+ Value = *(volatile UINT64*)Address;
+ MemoryFence ();
+ }
}
FilterAfterMmIoRead (FilterWidth64, Address, &Value);
@@ -326,6 +369,8 @@ MmioRead64 (
If 64-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 64-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -343,9 +388,13 @@ MmioWrite64 (
Flag = FilterBeforeMmIoWrite (FilterWidth64, Address, &Value);
if (Flag) {
- MemoryFence ();
- *(volatile UINT64*)Address = Value;
- MemoryFence ();
+ if (IsTdxGuest ()) {
+ TdMmioWrite64 (Address, Value);
+ } else {
+ MemoryFence ();
+ *(volatile UINT64*)Address = Value;
+ MemoryFence ();
+ }
}
FilterAfterMmIoWrite (FilterWidth64, Address, &Value);
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibFifo.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibFifo.c
new file mode 100644
index 000000000000..9e243543cfe2
--- /dev/null
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibFifo.c
@@ -0,0 +1,216 @@
+/** @file
+ IoFifo read/write routines.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseIoLibIntrinsicInternal.h"
+#include "IoLibSev.h"
+#include "IoLibTdx.h"
+#include <Library/TdxLib.h>
+
+/**
+ 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
+IoReadFifo8 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoReadFifo8 (Port, Count, Buffer);
+ } else {
+ SevIoReadFifo8 (Port, Count, Buffer);
+ }
+}
+
+/**
+ Writes a block of memory into an 8-bit I/O port fifo.
+
+ Writes the 8-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ 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
+IoWriteFifo8 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoWriteFifo8 (Port, Count, Buffer);
+ } else {
+ SevIoWriteFifo8 (Port, Count, Buffer);
+ }
+}
+
+/**
+ Reads a 16-bit I/O port fifo into a block of memory.
+
+ Reads the 16-bit I/O fifo port specified by Port.
+ The port is read Count times, and the read data is
+ stored in the provided Buffer.
+
+ This function must guarantee that all I/O read and write operations are
+ serialized.
+
+ If 16-bit I/O port operations are not supported, then ASSERT().
+
+ 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
+IoReadFifo16 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoReadFifo16 (Port, Count, Buffer);
+ } else {
+ SevIoReadFifo16 (Port, Count, Buffer);
+ }
+}
+
+/**
+ Writes a block of memory into a 16-bit I/O port fifo.
+
+ Writes the 16-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 16-bit I/O port operations are not supported, then ASSERT().
+
+ 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
+IoWriteFifo16 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoWriteFifo16 (Port, Count, Buffer);
+ } else {
+ SevIoWriteFifo16 (Port, Count, Buffer);
+ }
+}
+
+/**
+ Reads a 32-bit I/O port fifo into a block of memory.
+
+ Reads the 32-bit I/O fifo port specified by Port.
+ The port is read Count times, and the read data is
+ stored in the provided Buffer.
+
+ This function must guarantee that all I/O read and write operations are
+ serialized.
+
+ If 32-bit I/O port operations are not supported, then ASSERT().
+
+ 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
+IoReadFifo32 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoReadFifo32 (Port, Count, Buffer);
+ } else {
+ SevIoReadFifo32 (Port, Count, Buffer);
+ }
+}
+
+/**
+ Writes a block of memory into a 32-bit I/O port fifo.
+
+ Writes the 32-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 32-bit I/O port operations are not supported, then ASSERT().
+
+ 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
+IoWriteFifo32 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ if (IsTdxGuest ()) {
+ TdIoWriteFifo32 (Port, Count, Buffer);
+ } else {
+ SevIoWriteFifo32 (Port, Count, Buffer);
+ }
+}
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
index ecf9ed61911f..42b5d5743a4f 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
@@ -17,6 +17,7 @@
#include "BaseIoLibIntrinsicInternal.h"
+#include "IoLibTdx.h"
/**
Reads an 8-bit I/O port.
@@ -25,7 +26,9 @@
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().
+ If 8-bit I/O port operations are not supported, then ASSERT()
+
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
@param Port The I/O port to read.
@@ -43,7 +46,11 @@ IoRead8 (
Flag = FilterBeforeIoRead (FilterWidth8, Port, &Data);
if (Flag) {
- __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
+ if (IsTdxGuest ()) {
+ Data = TdIoRead8 (Port);
+ } else {
+ __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
+ }
}
FilterAfterIoRead (FilterWidth8, Port, &Data);
@@ -59,6 +66,8 @@ IoRead8 (
If 8-bit I/O port operations are not supported, then ASSERT().
+ For Td guest 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.
@@ -76,7 +85,11 @@ IoWrite8 (
Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value);
if (Flag) {
- __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ if (IsTdxGuest ()) {
+ TdIoWrite8 (Port, Value);
+ } else {
+ __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ }
}
FilterAfterIoWrite (FilterWidth8, Port, &Value);
@@ -93,6 +106,8 @@ IoWrite8 (
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
+
@param Port The I/O port to read.
@return The value read.
@@ -111,7 +126,11 @@ IoRead16 (
Flag = FilterBeforeIoRead (FilterWidth16, Port, &Data);
if (Flag) {
+ if (IsTdxGuest ()) {
+ Data = TdIoRead16 (Port);
+ } else {
__asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
+ }
}
FilterAfterIoRead (FilterWidth16, Port, &Data);
@@ -128,6 +147,8 @@ IoRead16 (
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -148,7 +169,11 @@ IoWrite16 (
Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value);
if (Flag) {
- __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ if (IsTdxGuest ()) {
+ TdIoWrite16 (Port, Value);
+ } else {
+ __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ }
}
FilterAfterIoWrite (FilterWidth16, Port, &Value);
@@ -165,6 +190,8 @@ IoWrite16 (
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
+
@param Port The I/O port to read.
@return The value read.
@@ -183,7 +210,11 @@ IoRead32 (
Flag = FilterBeforeIoRead (FilterWidth32, Port, &Data);
if (Flag) {
- __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
+ if (IsTdxGuest ()) {
+ Data = TdIoRead32 (Port);
+ } else {
+ __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
+ }
}
FilterAfterIoRead (FilterWidth32, Port, &Data);
@@ -200,6 +231,8 @@ IoRead32 (
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -219,7 +252,11 @@ IoWrite32 (
Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value);
if (Flag) {
- __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ if (IsTdxGuest ()) {
+ TdIoWrite32 (Port, Value);
+ } else {
+ __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
+ }
}
FilterAfterIoWrite (FilterWidth32, Port, &Value);
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c
new file mode 100644
index 000000000000..d321cc9f00be
--- /dev/null
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdx.c
@@ -0,0 +1,735 @@
+/** @file
+ TDX I/O Library routines.
+
+ Copyright (c) 2020-2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "BaseIoLibIntrinsicInternal.h"
+#include <Include/IndustryStandard/Tdx.h>
+#include <Library/TdxLib.h>
+#include <Library/BaseLib.h>
+#include <Base.h>
+#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 = FALSE;
+BOOLEAN mTdxProbed = FALSE;
+
+/**
+ Check if it is Tdx guest.
+
+ @return TRUE It is Tdx guest
+ @return FALSE It is not Tdx guest
+
+**/
+BOOLEAN
+EFIAPI
+IsTdxGuest (
+ VOID
+ )
+{
+ UINT32 Eax;
+ UINT32 Ebx;
+ UINT32 Ecx;
+ UINT32 Edx;
+ UINT32 LargestEax;
+
+ if (mTdxProbed) {
+ return mTdxEnabled;
+ }
+
+ mTdxEnabled = FALSE;
+
+ do {
+ AsmCpuid (0, &LargestEax, &Ebx, &Ecx, &Edx);
+
+ if (Ebx != SIGNATURE_32 ('G', 'e', 'n', 'u')
+ || Edx != SIGNATURE_32 ('i', 'n', 'e', 'I')
+ || Ecx != SIGNATURE_32 ('n', 't', 'e', 'l')) {
+ break;
+ }
+
+ AsmCpuid (1, NULL, NULL, &Ecx, NULL);
+ if ((Ecx & BIT31) == 0) {
+ break;
+ }
+
+ if (LargestEax < 0x21) {
+ break;
+ }
+
+ AsmCpuidEx (0x21, 0, &Eax, &Ebx, &Ecx, &Edx);
+ if (Ebx != SIGNATURE_32 ('I', 'n', 't', 'e')
+ || Edx != SIGNATURE_32 ('l', 'T', 'D', 'X')
+ || Ecx != SIGNATURE_32 (' ', ' ', ' ', ' ')) {
+ break;
+ }
+
+ mTdxEnabled = TRUE;
+ }while (FALSE);
+
+ mTdxProbed = 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 = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCESS_READ, Port, 0, &Val);
+ if (Status != 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) == 0);
+
+ Status = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCESS_READ, Port, 0, &Val);
+ if (Status != 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) == 0);
+
+ Status = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCESS_READ, Port, 0, &Val);
+ if (Status != 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 = Value;
+ Status = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCESS_WRITE, Port, Val, 0);
+ if (Status != 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) == 0);
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCESS_WRITE, Port, Val, 0);
+ if (Status != 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) == 0);
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_IO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCESS_WRITE, Port, Val, 0);
+ if (Status != 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;
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCESS_READ, Address, 0, &Value);
+ if (Status != 0) {
+ Value = *(volatile UINT64*) Address;
+ }
+ MemoryFence ();
+
+ 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;
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_1, TDVMCALL_ACCESS_WRITE, Address, Val, 0);
+ if (Status != 0) {
+ *(volatile UINT8*) Address = Value;
+ }
+ MemoryFence ();
+
+ 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;
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCESS_READ, Address, 0, &Value);
+ if (Status != 0) {
+ Value = *(volatile UINT64*) Address;
+ }
+ MemoryFence ();
+
+ 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) == 0);
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_2, TDVMCALL_ACCESS_WRITE, Address, Val, 0);
+ if (Status != 0) {
+ *(volatile UINT16*) Address = Value;
+ }
+ MemoryFence ();
+
+ 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;
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCESS_READ, Address, 0, &Value);
+ if (Status != 0) {
+ Value = *(volatile UINT64*)Address;
+ }
+ MemoryFence ();
+
+ 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) == 0);
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_4, TDVMCALL_ACCESS_WRITE, Address, Val, 0);
+ if (Status != 0) {
+ *(volatile UINT32*)Address = Value;
+ }
+ MemoryFence ();
+
+ 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;
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_8, TDVMCALL_ACCESS_READ, Address, 0, &Value);
+ if (Status != 0) {
+ Value = *(volatile UINT64*)Address;
+ }
+ MemoryFence ();
+
+ 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) == 0);
+
+ Address |= TdSharedPageMask ();
+
+ MemoryFence ();
+ Val = Value;
+ Status = TdVmCall (TDVMCALL_MMIO, TDVMCALL_ACCESS_SIZE_8, TDVMCALL_ACCESS_WRITE, Address, Val, 0);
+ if (Status != 0) {
+ *(volatile UINT64*)Address = Value;
+ }
+ MemoryFence ();
+ 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 = (UINT8 *) Buffer;
+ for (Index = 0; Index < Count; Index++) {
+ Buf8[Index] = 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 = (UINT8 *) Buffer;
+ for (Index = 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 = (UINT16 *) Buffer;
+ for (Index = 0; Index < Count; Index++) {
+ Buf16[Index] = 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 = (UINT16 *) Buffer;
+ for (Index = 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 = (UINT32 *) Buffer;
+ for (Index = 0; Index < Count; Index++) {
+ Buf32[Index] = 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 = (UINT32 *) Buffer;
+ for (Index = 0; Index < Count; Index++) {
+ TdIoWrite32 (Port, Buf32[Index]);
+ }
+}
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c
new file mode 100644
index 000000000000..f518d8ffd825
--- /dev/null
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibInternalTdxNull.c
@@ -0,0 +1,499 @@
+/** @file
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <Library/BaseLib.h>
+#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/IoLibMsc.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
index d2bc5f527cf6..4d7945ae496f 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
@@ -16,6 +16,7 @@
#include "BaseIoLibIntrinsicInternal.h"
+#include "IoLibTdx.h"
//
// Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
@@ -54,6 +55,8 @@ void _ReadWriteBarrier (void);
If 8-bit I/O port operations are not supported, then ASSERT().
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
+
@param Port The I/O port to read.
@return The value read.
@@ -70,9 +73,13 @@ IoRead8 (
Flag = FilterBeforeIoRead (FilterWidth8, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- Value = (UINT8)_inp ((UINT16)Port);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ Value = TdIoRead8 (Port);
+ } else {
+ _ReadWriteBarrier ();
+ Value = (UINT8)_inp ((UINT16)Port);
+ _ReadWriteBarrier ();
+ }
}
FilterAfterIoRead (FilterWidth8, Port, &Value);
@@ -88,6 +95,8 @@ IoRead8 (
If 8-bit I/O port operations are not supported, then ASSERT().
+ For Td guest 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.
@@ -105,9 +114,13 @@ IoWrite8 (
Flag = FilterBeforeIoWrite(FilterWidth8, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- (UINT8)_outp ((UINT16)Port, Value);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ TdIoWrite8 (Port, Value);
+ } else {
+ _ReadWriteBarrier ();
+ (UINT8)_outp ((UINT16)Port, Value);
+ _ReadWriteBarrier ();
+ }
}
FilterAfterIoWrite (FilterWidth8, Port, &Value);
@@ -124,6 +137,8 @@ IoWrite8 (
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
+
@param Port The I/O port to read.
@return The value read.
@@ -142,9 +157,13 @@ IoRead16 (
Flag = FilterBeforeIoRead (FilterWidth16, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- Value = _inpw ((UINT16)Port);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ Value = TdIoRead16 (Port);
+ } else {
+ _ReadWriteBarrier ();
+ Value = _inpw ((UINT16)Port);
+ _ReadWriteBarrier ();
+ }
}
FilterBeforeIoRead (FilterWidth16, Port, &Value);
@@ -161,6 +180,8 @@ IoRead16 (
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -180,9 +201,13 @@ IoWrite16 (
Flag = FilterBeforeIoWrite(FilterWidth16, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- _outpw ((UINT16)Port, Value);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ TdIoWrite16 (Port, Value);
+ } else {
+ _ReadWriteBarrier ();
+ _outpw ((UINT16)Port, Value);
+ _ReadWriteBarrier ();
+ }
}
FilterAfterIoWrite (FilterWidth16, Port, &Value);
@@ -199,6 +224,8 @@ IoWrite16 (
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest TDVMCALL_IO is invoked to read I/O port.
+
@param Port The I/O port to read.
@return The value read.
@@ -217,9 +244,13 @@ IoRead32 (
Flag = FilterBeforeIoRead(FilterWidth32, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- Value = _inpd ((UINT16)Port);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ Value = TdIoRead32 (Port);
+ } else {
+ _ReadWriteBarrier ();
+ Value = _inpd ((UINT16)Port);
+ _ReadWriteBarrier ();
+ }
}
FilterAfterIoRead (FilterWidth32, Port, &Value);
@@ -236,6 +267,8 @@ IoRead32 (
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
+ For Td guest 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.
@@ -255,9 +288,13 @@ IoWrite32 (
Flag = FilterBeforeIoWrite(FilterWidth32, Port, &Value);
if (Flag) {
- _ReadWriteBarrier ();
- _outpd ((UINT16)Port, Value);
- _ReadWriteBarrier ();
+ if (IsTdxGuest ()) {
+ TdIoWrite32 (Port, Value);
+ } else {
+ _ReadWriteBarrier ();
+ _outpd ((UINT16)Port, Value);
+ _ReadWriteBarrier ();
+ }
}
FilterAfterIoWrite (FilterWidth32, Port, &Value);
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibSev.h b/MdePkg/Library/BaseIoLibIntrinsic/IoLibSev.h
new file mode 100644
index 000000000000..e219f8a36a47
--- /dev/null
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibSev.h
@@ -0,0 +1,166 @@
+/** @file
+ Header file for SEV IO library.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef IOLIB_SEV_H_
+#define IOLIB_SEV_H_
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Reads an 8-bit I/O port fifo into a block of memory.
+
+ Reads the 8-bit I/O fifo port specified by Port.
+ The port is read Count times, and the read data is
+ stored in the provided Buffer.
+
+ This function must guarantee that all I/O read and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to read.
+ @param Count The number of times to read I/O port.
+ @param Buffer The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+SevIoReadFifo8 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Writes a block of memory into an 8-bit I/O port fifo.
+
+ Writes the 8-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to write.
+ @param Count The number of times to write I/O port.
+ @param Buffer The buffer to retrieve the write data from.
+
+**/
+VOID
+EFIAPI
+SevIoWriteFifo8 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ Reads an 8-bit I/O port fifo into a block of memory.
+
+ Reads the 8-bit I/O fifo port specified by Port.
+ The port is read Count times, and the read data is
+ stored in the provided Buffer.
+
+ This function must guarantee that all I/O read and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to read.
+ @param Count The number of times to read I/O port.
+ @param Buffer The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+SevIoReadFifo16 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Writes a block of memory into an 8-bit I/O port fifo.
+
+ Writes the 8-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to write.
+ @param Count The number of times to write I/O port.
+ @param Buffer The buffer to retrieve the write data from.
+
+**/
+VOID
+EFIAPI
+SevIoWriteFifo16 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ Reads an 8-bit I/O port fifo into a block of memory.
+
+ Reads the 8-bit I/O fifo port specified by Port.
+ The port is read Count times, and the read data is
+ stored in the provided Buffer.
+
+ This function must guarantee that all I/O read and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to read.
+ @param Count The number of times to read I/O port.
+ @param Buffer The buffer to store the read data into.
+
+**/
+VOID
+EFIAPI
+SevIoReadFifo32 (
+ IN UINTN Port,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Writes a block of memory into an 8-bit I/O port fifo.
+
+ Writes the 8-bit I/O fifo port specified by Port.
+ The port is written Count times, and the write data is
+ retrieved from the provided Buffer.
+
+ This function must guarantee that all I/O write and write operations are
+ serialized.
+
+ If 8-bit I/O port operations are not supported, then ASSERT().
+
+ @param Port The I/O port to write.
+ @param Count The number of times to write I/O port.
+ @param Buffer The buffer to retrieve the write data from.
+
+**/
+VOID
+EFIAPI
+SevIoWriteFifo32 (
+ IN UINTN Port,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+#endif
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h b/MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h
new file mode 100644
index 000000000000..3aad197d3b39
--- /dev/null
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibTdx.h
@@ -0,0 +1,411 @@
+/** @file
+ Header file for Tdx IO library.
+
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+ 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
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm
index 106f8881c55c..d02286b4d518 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm
+++ b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifoSev.nasm
@@ -67,14 +67,14 @@ ASM_PFX(SevNoRepIo):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
-; IoReadFifo8 (
+; SevIoReadFifo8 (
; IN UINTN Port, // rcx
; IN UINTN Size, // rdx
; OUT VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoReadFifo8)
-ASM_PFX(IoReadFifo8):
+global ASM_PFX(SevIoReadFifo8)
+ASM_PFX(SevIoReadFifo8):
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
@@ -103,14 +103,14 @@ ASM_PFX(IoReadFifo8):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
-; IoReadFifo16 (
+; SevIoReadFifo16 (
; IN UINTN Port, // rcx
; IN UINTN Size, // rdx
; OUT VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoReadFifo16)
-ASM_PFX(IoReadFifo16):
+global ASM_PFX(SevIoReadFifo16)
+ASM_PFX(SevIoReadFifo16):
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
@@ -139,14 +139,14 @@ ASM_PFX(IoReadFifo16):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
-; IoReadFifo32 (
+; SevIoReadFifo32 (
; IN UINTN Port, // rcx
; IN UINTN Size, // rdx
; OUT VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoReadFifo32)
-ASM_PFX(IoReadFifo32):
+global ASM_PFX(SevIoReadFifo32)
+ASM_PFX(SevIoReadFifo32):
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
@@ -181,8 +181,8 @@ ASM_PFX(IoReadFifo32):
; IN VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoWriteFifo8)
-ASM_PFX(IoWriteFifo8):
+global ASM_PFX(SevIoWriteFifo8)
+ASM_PFX(SevIoWriteFifo8):
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
@@ -211,14 +211,14 @@ ASM_PFX(IoWriteFifo8):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
-; IoWriteFifo16 (
+; SevIoWriteFifo16 (
; IN UINTN Port, // rcx
; IN UINTN Size, // rdx
; IN VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoWriteFifo16)
-ASM_PFX(IoWriteFifo16):
+global ASM_PFX(SevIoWriteFifo16)
+ASM_PFX(SevIoWriteFifo16):
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
@@ -247,14 +247,14 @@ ASM_PFX(IoWriteFifo16):
;------------------------------------------------------------------------------
; VOID
; EFIAPI
-; IoWriteFifo32 (
+; SevIoWriteFifo32 (
; IN UINTN Port, // rcx
; IN UINTN Size, // rdx
; IN VOID *Buffer // r8
; );
;------------------------------------------------------------------------------
-global ASM_PFX(IoWriteFifo32)
-ASM_PFX(IoWriteFifo32):
+global ASM_PFX(SevIoWriteFifo32)
+ASM_PFX(SevIoWriteFifo32):
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
--
2.29.2.windows.2
next prev parent reply other threads:[~2021-10-05 3:40 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-05 3:39 [PATCH V2 00/28] Enable Intel TDX in OvmfPkg (Config-A) Min Xu
2021-10-05 3:39 ` [PATCH V2 01/28] OvmfPkg: Copy Main.asm from UefiCpuPkg to OvmfPkg's ResetVector Min Xu
2021-10-05 3:39 ` [PATCH V2 02/28] OvmfPkg: Enable TDX in ResetVector Min Xu
2021-10-05 3:39 ` [PATCH V2 03/28] OvmfPkg: Merge TEMP_MEM entries in Tdx metadata Min Xu
2021-10-05 3:39 ` [PATCH V2 04/28] MdePkg: Add Tdx.h Min Xu
2021-10-12 7:48 ` [edk2-devel] " Gerd Hoffmann
2021-10-05 3:39 ` [PATCH V2 05/28] MdePkg: Add TdxLib to wrap Tdx operations Min Xu
2021-10-12 8:22 ` [edk2-devel] " Gerd Hoffmann
2021-10-13 12:13 ` Min Xu
2021-10-14 5:30 ` Gerd Hoffmann
2021-10-22 2:06 ` Min Xu
2021-10-05 3:39 ` Min Xu [this message]
2021-10-12 10:05 ` [edk2-devel] [PATCH V2 06/28] MdePkg: Update BaseIoLibIntrinsicSev to support Tdx Gerd Hoffmann
2021-10-13 13:40 ` Min Xu
2021-10-14 5:37 ` Gerd Hoffmann
2021-10-14 6:24 ` Min Xu
2021-10-14 9:03 ` Gerd Hoffmann
2021-10-22 5:23 ` Min Xu
2021-10-05 3:39 ` [PATCH V2 07/28] UefiCpuPkg: Support TDX in BaseXApicX2ApicLib Min Xu
2021-10-12 10:15 ` [edk2-devel] " Gerd Hoffmann
2021-10-13 14:06 ` Min Xu
2021-10-13 5:30 ` Ni, Ray
2021-10-14 7:58 ` Min Xu
2021-10-05 3:39 ` [PATCH V2 08/28] UefiCpuPkg: Add VmTdExitLibNull Min Xu
2021-10-05 3:39 ` [PATCH V2 09/28] UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmTdExitLib library Min Xu
2021-10-05 3:39 ` [PATCH V2 10/28] OvmfPkg: Prepare OvmfPkg " Min Xu
2021-10-05 3:39 ` [PATCH V2 11/28] OvmfPkg: Implement library support for VmTdExitLib in Ovmf Min Xu
2021-10-05 3:39 ` [PATCH V2 12/28] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VE exception Min Xu
2021-10-12 10:27 ` [edk2-devel] " Gerd Hoffmann
2021-10-26 5:06 ` Min Xu
2021-10-26 6:11 ` Gerd Hoffmann
2021-10-26 8:23 ` Min Xu
2021-10-26 10:24 ` Gerd Hoffmann
2021-10-26 12:09 ` Min Xu
2021-10-27 7:19 ` Gerd Hoffmann
2021-10-28 1:59 ` Yao, Jiewen
2021-10-28 15:35 ` Brijesh Singh
2021-10-28 15:52 ` Yao, Jiewen
2021-10-28 18:28 ` Lendacky, Thomas
2021-10-29 0:17 ` Yao, Jiewen
2021-10-29 4:52 ` Gerd Hoffmann
2021-10-29 7:51 ` Min Xu
2021-10-29 11:40 ` Gerd Hoffmann
2021-11-01 13:54 ` Sami Mujawar
2021-11-01 13:57 ` Yao, Jiewen
[not found] ` <16B2583BF2C9DB9C.5572@groups.io>
2021-10-29 0:20 ` Yao, Jiewen
2021-10-29 0:25 ` Brijesh Singh
[not found] ` <16B20F4407499229.28171@groups.io>
2021-10-28 2:07 ` Yao, Jiewen
2021-10-28 8:24 ` Gerd Hoffmann
2021-10-05 3:39 ` [PATCH V2 13/28] UefiCpuPkg: Enable Tdx support in MpInitLib Min Xu
2021-10-12 10:31 ` [edk2-devel] " Gerd Hoffmann
2021-10-14 0:27 ` Min Xu
2021-10-14 6:04 ` Gerd Hoffmann
2021-10-14 6:31 ` Min Xu
2021-10-14 6:56 ` Gerd Hoffmann
2021-10-13 6:01 ` Ni, Ray
2021-10-14 8:22 ` Min Xu
2021-10-05 3:39 ` [PATCH V2 14/28] OvmfPkg: Update SecEntry.nasm to support Tdx Min Xu
2021-10-12 10:38 ` [edk2-devel] " Gerd Hoffmann
2021-10-14 0:55 ` Min Xu
2021-10-14 6:51 ` Gerd Hoffmann
2021-10-05 3:39 ` [PATCH V2 15/28] OvmfPkg: Add IntelTdx.h in OvmfPkg/Include/IndustryStandard Min Xu
2021-10-05 3:39 ` [PATCH V2 16/28] OvmfPkg: Add TdxMailboxLib Min Xu
2021-10-05 3:39 ` [PATCH V2 17/28] MdePkg: Add EFI_RESOURCE_ATTRIBUTE_ENCRYPTED in PiHob.h Min Xu
2021-10-05 3:39 ` [PATCH V2 18/28] OvmfPkg: Enable Tdx in SecMain.c Min Xu
2021-10-05 3:39 ` [PATCH V2 19/28] OvmfPkg: Check Tdx in QemuFwCfgPei to avoid DMA operation Min Xu
2021-10-05 3:39 ` [PATCH V2 20/28] MdeModulePkg: EFER should not be changed in TDX Min Xu
2021-10-05 3:39 ` [PATCH V2 21/28] OvmfPkg: Update PlatformPei to support TDX Min Xu
2021-10-13 4:49 ` [edk2-devel] " Gerd Hoffmann
2021-10-15 1:31 ` Yao, Jiewen
2021-10-15 5:45 ` Gerd Hoffmann
2021-10-15 6:41 ` Yao, Jiewen
2021-10-05 3:39 ` [PATCH V2 22/28] UefiCpuPkg: Define ConfidentialComputingGuestAttr (Temp) Min Xu
2021-10-05 3:39 ` [PATCH V2 23/28] OvmfPkg: Update AcpiPlatformDxe to alter MADT table Min Xu
2021-10-05 3:39 ` [PATCH V2 24/28] OvmfPkg: Add TdxDxe driver Min Xu
2021-10-12 11:50 ` [edk2-devel] " Gerd Hoffmann
2021-10-18 8:38 ` Min Xu
2021-10-05 3:39 ` [PATCH V2 25/28] OvmfPkg/BaseMemEncryptTdxLib: Add TDX helper library Min Xu
2021-10-12 12:13 ` [edk2-devel] " Gerd Hoffmann
2021-10-05 3:39 ` [PATCH V2 26/28] OvmfPkg/QemuFwCfgLib: Support Tdx in QemuFwCfgDxe Min Xu
2021-10-05 3:39 ` [PATCH V2 27/28] OvmfPkg: Update IoMmuDxe to support TDX Min Xu
2021-10-12 12:15 ` [edk2-devel] " Gerd Hoffmann
2021-10-14 2:11 ` Min Xu
2021-10-05 3:39 ` [PATCH V2 28/28] OvmfPkg: Add LocalApicTimerDxe Min Xu
2021-10-12 13:02 ` [edk2-devel] " Gerd Hoffmann
2021-10-14 5:20 ` Min Xu
2021-10-15 1:21 ` Yao, Jiewen
2021-10-25 7:37 ` Min Xu
2021-10-25 11:27 ` Gerd Hoffmann
2021-10-26 1:29 ` Min Xu
2021-10-26 5:50 ` Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=78bc0164be0e6adb1edf4454bdc3aaf1d55a2771.1633401643.git.min.m.xu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox