aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2025-04-23 18:02:54 +0000
committerWarner Losh <imp@FreeBSD.org>2025-04-23 18:02:54 +0000
commit8f6bda97a4734bec74d5787766b177112dc8a3f5 (patch)
tree36b30c90ce307f59ff198416fe65bb1c405e68f3
parent5d8674f2bdd536124b1dd026dfa729a1376b3cac (diff)
-rw-r--r--MdePkg/Include/AArch64/AArch64.h5
-rw-r--r--MdePkg/Include/AArch64/AArch64Mmu.h1
-rw-r--r--MdePkg/Include/Base.h10
-rw-r--r--MdePkg/Include/Guid/ImageAuthentication.h37
-rw-r--r--MdePkg/Include/Guid/Rng.h155
-rw-r--r--MdePkg/Include/Guid/StatusCodeDataTypeId.h6
-rwxr-xr-xMdePkg/Include/IndustryStandard/Cxl20.h41
-rw-r--r--MdePkg/Include/IndustryStandard/Cxl30.h59
-rw-r--r--MdePkg/Include/IndustryStandard/Cxl31.h47
-rw-r--r--MdePkg/Include/IndustryStandard/IpmiSerial.h66
-rwxr-xr-x[-rw-r--r--]MdePkg/Include/IndustryStandard/ServiceProcessorManagementInterfaceTable.h0
-rw-r--r--MdePkg/Include/IndustryStandard/Tpm12.h4
-rw-r--r--MdePkg/Include/IndustryStandard/Tpm20.h4
-rw-r--r--MdePkg/Include/IndustryStandard/Tpm2Acpi.h3
-rw-r--r--MdePkg/Include/IndustryStandard/Ufs.h1022
-rw-r--r--MdePkg/Include/IndustryStandard/UfsHci.h533
-rw-r--r--MdePkg/Include/Library/ArmLib.h2
-rw-r--r--MdePkg/Include/Library/StackCheckLib.h78
-rw-r--r--MdePkg/Include/Library/StandaloneMmCoreEntryPoint.h91
-rw-r--r--MdePkg/Include/Library/UefiUsbLib.h131
-rw-r--r--MdePkg/Include/Pi/PiHob.h3
-rw-r--r--MdePkg/Include/Pi/PiStatusCode.h12
-rw-r--r--MdePkg/Include/Ppi/Rng.h27
-rw-r--r--MdePkg/Include/Protocol/AtaPassThru.h4
-rw-r--r--MdePkg/Include/Protocol/BootManagerPolicy.h13
-rw-r--r--MdePkg/Include/Protocol/CcMeasurement.h7
-rw-r--r--MdePkg/Include/Protocol/DebugSupport.h63
-rw-r--r--MdePkg/Include/Protocol/FirmwareManagement.h5
-rw-r--r--MdePkg/Include/Protocol/PxeBaseCode.h2
-rw-r--r--MdePkg/Include/Protocol/Rng.h142
-rw-r--r--MdePkg/Include/Uefi/UefiSpec.h43
-rw-r--r--MdePkg/Library/BaseFdtLib/LibFdtSupport.h22
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoff.c44
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf1
-rw-r--r--MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c10
-rw-r--r--MdePkg/Library/BaseRngLib/AArch64/ArmRng.S2
-rw-r--r--MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm2
-rw-r--r--MdePkg/Library/BaseRngLib/AArch64/ArmRng.h2
-rw-r--r--MdePkg/Library/BaseRngLib/BaseRngLibInternals.h7
-rw-r--r--MdePkg/Library/BaseRngLib/Rand/RdRand.c37
-rw-r--r--MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf1
-rw-r--r--MdePkg/Library/DxeRngLib/DxeRngLib.c7
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S56
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c70
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c65
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf38
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c135
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni17
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf53
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c112
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c162
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf68
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm63
-rw-r--r--MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf2
-rw-r--r--MdePkg/Library/PeiRngLib/PeiRngLib.c229
-rw-r--r--MdePkg/Library/PeiRngLib/PeiRngLib.inf41
-rw-r--r--MdePkg/Library/PeiRngLib/PeiRngLib.uni12
-rw-r--r--MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf2
-rw-r--r--MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf1
-rw-r--r--MdePkg/Library/StackCheckLib/Readme.md197
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLib.inf56
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c2
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c1
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c1
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c1
-rw-r--r--MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf33
-rw-r--r--MdePkg/Library/StandaloneMmCoreEntryPoint/X64/StandaloneMmCoreEntryPoint.c69
-rw-r--r--MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf1
-rw-r--r--MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf1
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathToText.c12
-rw-r--r--MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf1
-rw-r--r--MdePkg/Library/UefiUsbLib/UefiUsbLib.inf3
-rw-r--r--MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h2
-rw-r--r--MdePkg/Library/UefiUsbLib/UsbDxeLib.c533
-rw-r--r--MdePkg/MdeLibs.dsc.inc36
-rw-r--r--MdePkg/MdePkg.dec82
-rw-r--r--MdePkg/MdePkg.dsc11
-rw-r--r--MdePkg/Test/MdePkgHostTest.dsc1
-rw-r--r--MdePkg/Test/Mock/Include/GoogleTest/Library/MockSafeIntLib.h1001
-rw-r--r--MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.cpp116
-rw-r--r--MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.inf33
89 files changed, 6052 insertions, 345 deletions
diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h
index 58f884627780..e6b93b71cf68 100644
--- a/MdePkg/Include/AArch64/AArch64.h
+++ b/MdePkg/Include/AArch64/AArch64.h
@@ -66,6 +66,7 @@
#define ARM_HCR_AMO BIT5
#define ARM_HCR_TSC BIT19
#define ARM_HCR_TGE BIT27
+#define ARM_HCR_E2H BIT34
// Exception Syndrome Register
#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr))
@@ -129,6 +130,10 @@
// build for ARMv8.0, we need to define the register here.
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+// The RNDR register is not recognized by older assemblers,
+// so we need to define it here
+#define RNDR S3_3_C2_C4_0
+
#define VECTOR_BASE(tbl) \
.section .text.##tbl##,"ax"; \
.align 11; \
diff --git a/MdePkg/Include/AArch64/AArch64Mmu.h b/MdePkg/Include/AArch64/AArch64Mmu.h
index 0d9f98b63077..138857089526 100644
--- a/MdePkg/Include/AArch64/AArch64Mmu.h
+++ b/MdePkg/Include/AArch64/AArch64Mmu.h
@@ -67,6 +67,7 @@
#define TT_NS BIT5
#define TT_AF BIT10
+#define TT_NG BIT11
#define TT_SH_NON_SHAREABLE (0x0 << 8)
#define TT_SH_OUTER_SHAREABLE (0x2 << 8)
diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h
index 72bf6f31366a..6989b10f9e0b 100644
--- a/MdePkg/Include/Base.h
+++ b/MdePkg/Include/Base.h
@@ -800,12 +800,12 @@ typedef UINTN *BASE_LIST;
@param Message Raised compiler diagnostic message when expression is false.
**/
-#ifdef MDE_CPU_EBC
-#define STATIC_ASSERT(Expression, Message)
-#elif defined (_MSC_EXTENSIONS) || defined (__cplusplus)
+#if defined (__cplusplus)
#define STATIC_ASSERT static_assert
-#else
+#elif defined (__GNUC__) || defined (__clang__)
#define STATIC_ASSERT _Static_assert
+#elif defined (_MSC_EXTENSIONS)
+#define STATIC_ASSERT static_assert
#endif
//
@@ -888,7 +888,7 @@ STATIC_ASSERT (ALIGNOF (__VERIFY_INT32_ENUM_SIZE) == sizeof (__VERIFY_INT32_ENUM
@return A pointer to the structure from one of it's elements.
**/
-#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
+#define BASE_CR(Record, TYPE, Field) ((TYPE *) (VOID *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
/**
Checks whether a value is a power of two.
diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Guid/ImageAuthentication.h
index f4c472d75a59..47489cc82328 100644
--- a/MdePkg/Include/Guid/ImageAuthentication.h
+++ b/MdePkg/Include/Guid/ImageAuthentication.h
@@ -123,6 +123,19 @@ typedef struct {
EFI_TIME TimeOfRevocation;
} EFI_CERT_X509_SHA512;
+typedef UINT8 EFI_SM3_HASH[32];
+
+typedef struct {
+ ///
+ /// The SM3 hash of an X.509 certificate's To-Be-Signed contents.
+ ///
+ EFI_SM3_HASH ToBeSignedHash;
+ ///
+ /// The time that the certificate shall be considered to be revoked.
+ ///
+ EFI_TIME TimeOfRevocation;
+} EFI_CERT_X509_SM3;
+
#pragma pack()
///
@@ -167,6 +180,15 @@ typedef struct {
}
///
+/// This identifies a signature containing a SM3 hash. The SignatureSize shall always
+/// be 16 (size of SignatureOwner component) + 32 bytes.
+///
+#define EFI_CERT_SM3_GUID \
+ { \
+ 0x57347f87, 0x7a9b, 0x403a, { 0xb9, 0x3c, 0xdc, 0x4a, 0xfb, 0x7a, 0xe, 0xbc } \
+ }
+
+///
/// TThis identifies a signature containing a RSA-2048 signature of a SHA-1 hash. The
/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
/// SignatureOwner component) + 256 bytes.
@@ -191,6 +213,19 @@ typedef struct {
}
///
+/// This identifies a signature containing the SM3 hash of an X.509 certificate's To-Be-Signed
+/// contents, and a time of revocation. The SignatureHeader size shall always be 0. The
+/// SignatureSize shall always be 16 (size of the SignatureOwner component) + 32 bytes for
+/// an EFI_CERT_X509_SM3 structure. If the TimeOfRevocation is non-zero, the certificate should
+/// be considered to be revoked from that time and onwards, and otherwise the certificate shall
+/// be considered to always be revoked.
+///
+#define EFI_CERT_X509_SM3_GUID \
+ { \
+ 0x60d807e5, 0x10b4, 0x49a9, {0x93, 0x31, 0xe4, 0x4, 0x37, 0x88, 0x8d, 0x37 } \
+ }
+
+///
/// This identifies a signature containing a SHA-224 hash. The SignatureHeader size shall
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
/// 28 bytes.
@@ -344,5 +379,7 @@ extern EFI_GUID gEfiCertX509Sha256Guid;
extern EFI_GUID gEfiCertX509Sha384Guid;
extern EFI_GUID gEfiCertX509Sha512Guid;
extern EFI_GUID gEfiCertPkcs7Guid;
+extern EFI_GUID gEfiCertSm3Guid;
+extern EFI_GUID gEfiCertX509Sm3Guid;
#endif
diff --git a/MdePkg/Include/Guid/Rng.h b/MdePkg/Include/Guid/Rng.h
new file mode 100644
index 000000000000..acf0895b2b0d
--- /dev/null
+++ b/MdePkg/Include/Guid/Rng.h
@@ -0,0 +1,155 @@
+/** @file
+ Random Number Generator (RNG) GUIDs and structures shared across RNG interfaces.
+
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNG_GUID_H_
+#define RNG_GUID_H_
+
+typedef struct _EFI_RNG_INTERFACE EFI_RNG_INTERFACE;
+
+///
+/// A selection of EFI_RNG_PROTOCOL algorithms.
+/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
+/// vendors or other industry standards.
+///
+typedef EFI_GUID EFI_RNG_ALGORITHM;
+
+///
+/// The algorithms corresponds to SP800-90 as defined in
+/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
+/// Bit Generators", March 2007.
+///
+#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
+ { \
+ 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
+ { \
+ 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
+ { \
+ 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
+ }
+
+///
+/// The algorithms correspond to X9.31 as defined in
+/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
+/// the 3-Key Triple DES and AES Algorithm", January 2005.
+///
+#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
+ { \
+ 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
+ }
+#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
+ { \
+ 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
+ }
+
+///
+/// The "raw" algorithm, when supported, is intended to provide entropy directly from
+/// the source, without it going through some deterministic random bit generator.
+///
+#define EFI_RNG_ALGORITHM_RAW \
+ { \
+ 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
+ }
+
+///
+/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant
+/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be
+/// inclusive of different geographies.
+///
+#define EFI_RNG_ALGORITHM_ARM_RNDR \
+ { \
+ 0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \
+ }
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to this interface instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_INFO)(
+ IN EFI_RNG_INTERFACE *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to this interface instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_RNG)(
+ IN EFI_RNG_INTERFACE *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL,
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+///
+/// The Random Number Generator (RNG) interface provides random bits for use in
+/// applications, or entropy for seeding other random number generators.
+///
+/// This interface is shared between the RNG Protocol defined in the UEFI 2.4 Specification
+/// and the RNG PPI defined in the PI 1.9 Specification.
+///
+struct _EFI_RNG_INTERFACE {
+ EFI_RNG_GET_INFO GetInfo;
+ EFI_RNG_GET_RNG GetRNG;
+};
+
+extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
+extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
+extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
+extern EFI_GUID gEfiRngAlgorithmRaw;
+extern EFI_GUID gEfiRngAlgorithmArmRndr;
+
+#endif // #ifndef RNG_GUID_H_
diff --git a/MdePkg/Include/Guid/StatusCodeDataTypeId.h b/MdePkg/Include/Guid/StatusCodeDataTypeId.h
index 0e6b119a00ac..4b9c5a3b0297 100644
--- a/MdePkg/Include/Guid/StatusCodeDataTypeId.h
+++ b/MdePkg/Include/Guid/StatusCodeDataTypeId.h
@@ -107,6 +107,12 @@ extern EFI_GUID gEfiStatusCodeDataTypeStringGuid;
/// - EFI_COMPUTING_UNIT_MICROCODE_UPDATE_ERROR_DATA
/// - EFI_COMPUTING_UNIT_TIMER_EXPIRED_ERROR_DATA
/// - EFI_HOST_PROCESSOR_MISMATCH_ERROR_DATA
+/// - EFI_COMPUTING_UNIT_THERMAL_ERROR_DATA
+/// - EFI_CACHE_INIT_DATA
+/// - EFI_COMPUTING_UNIT_CPU_DISABLED_ERROR_DATA
+/// - EFI_MEMORY_EXTENDED_ERROR_DATA
+/// - EFI_STATUS_CODE_DIMM_NUMBER
+/// - EFI_MEMORY_MODULE_MISMATCH_ERROR_DATA
/// - EFI_MEMORY_RANGE_EXTENDED_DATA
/// - EFI_DEBUG_ASSERT_DATA
/// - EFI_STATUS_CODE_EXCEP_EXTENDED_DATA
diff --git a/MdePkg/Include/IndustryStandard/Cxl20.h b/MdePkg/Include/IndustryStandard/Cxl20.h
index 75c5ba4af6c4..25e279886c30 100755
--- a/MdePkg/Include/IndustryStandard/Cxl20.h
+++ b/MdePkg/Include/IndustryStandard/Cxl20.h
@@ -14,6 +14,7 @@
#define CXL20_H_
#include <IndustryStandard/Cxl11.h>
+#include <IndustryStandard/Acpi.h>
//
// CXL DVSEC IDs
@@ -103,6 +104,16 @@
#define CXL_MEM_DEVICE_MEDIA_STATUS_DISABLED 0x3
//
+// "CEDT" CXL Early Discovery Table
+// Compute Express Link Specification Revision 2.0 - Chapter 9.14.1
+//
+#define CXL_EARLY_DISCOVERY_TABLE_SIGNATURE SIGNATURE_32 ('C', 'E', 'D', 'T')
+
+#define CXL_EARLY_DISCOVERY_TABLE_REVISION_01 0x1
+
+#define CEDT_TYPE_CHBS 0x0
+
+//
// Ensure proper structure formats
//
#pragma pack(1)
@@ -458,6 +469,36 @@ typedef union {
UINT64 Uint64;
} CXL_MEMORY_DEVICE_STATUS_REGISTER;
+//
+// CEDT header
+// Compute Express Link Specification Revision 2.0 - Chapter 9.14.1.1
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+} CXL_EARLY_DISCOVERY_TABLE;
+
+//
+// Node header definition shared by all CEDT structure types
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Reserved;
+ UINT16 Length;
+} CEDT_STRUCTURE;
+
+//
+// Definition for CXL Host Bridge Structure (CHBS)
+// Compute Express Link Specification Revision 2.0 - Chapter 9.14.1.2
+//
+typedef struct {
+ CEDT_STRUCTURE Header;
+ UINT32 Uid;
+ UINT32 CxlVersion;
+ UINT32 Reserved;
+ UINT64 Base;
+ UINT64 Length;
+} CXL_HOST_BRIDGE_STRUCTURE;
+
#pragma pack()
#endif
diff --git a/MdePkg/Include/IndustryStandard/Cxl30.h b/MdePkg/Include/IndustryStandard/Cxl30.h
index 5b921891ef44..3f2688764b11 100644
--- a/MdePkg/Include/IndustryStandard/Cxl30.h
+++ b/MdePkg/Include/IndustryStandard/Cxl30.h
@@ -46,6 +46,14 @@
#define CXL_HDM_12_WAY_INTERLEAVING 0xA
//
+// "CEDT" CXL Early Discovery Table
+// Compute Express Link Specification Revision 3.0 - Chapter 9.17.1
+//
+#define CEDT_TYPE_CFMWS 0x1
+#define CEDT_TYPE_CXIMS 0x2
+#define CEDT_TYPE_RDPAS 0x3
+
+//
// Ensure proper structure formats
//
#pragma pack(1)
@@ -311,6 +319,57 @@ typedef struct {
CXL_3_0_CXL_TIMEOUT_AND_ISOLATION_STATUS TimeoutAndIsolationStatus;
} CXL_3_0_CXL_TIMEOUT_AND_ISOLATION_CAPABILITY_STRUCTURE;
+//
+// Definition for CXL Fixed Memory Window Structure (CFMWS)
+// Compute Express Link Specification Revision 3.0 - Chapter 9.17.1.3
+//
+// The number of entries in TargetList (Interleave Target List) shall
+// match the Number of Interleave Ways (NIW). The current maximum is 16.
+//
+typedef struct {
+ CEDT_STRUCTURE Header;
+ UINT32 Reserved;
+ UINT64 BaseHpa;
+ UINT64 WindowSize;
+ UINT8 EncodedInterleaveWays;
+ UINT8 InterleaveArithmetic;
+ UINT16 Reserved1;
+ UINT32 Granularity;
+ UINT16 Restrictions;
+ UINT16 QtgId;
+ UINT32 TargetList[16];
+} CXL_FIXED_MEMORY_WINDOW_STRUCTURE;
+
+//
+// Definition for CXL XOR Interleave Math Structure (CXIMS)
+// Compute Express Link Specification Revision 3.0 - Chapter 9.17.1.4
+//
+// The number of entries in XORMAPList depends on NIB. 4 is the current
+// maximum for 16-way interleaving.
+//
+typedef struct {
+ CEDT_STRUCTURE Header;
+ UINT16 Reserved;
+ UINT8 HBIG;
+ UINT8 NIB;
+ UINT64 XORMAPList[4];
+} CXL_XOR_INTERLEAVE_MATH_STRUCTURE;
+
+//
+// Definition for RCEC Downstream Port Association Structure (RDPAS)
+// Compute Express Link Specification Revision 3.0 - Chapter 9.17.1.5
+//
+// The errata released at CXL 3.2 fixed that RCEC BDF field overlaps
+// Protocol Type field.
+//
+typedef struct {
+ CEDT_STRUCTURE Header;
+ UINT16 SegmentNumber;
+ UINT16 Bdf;
+ UINT64 BaseAddress;
+ UINT8 ProtocolType;
+} RCEC_DOWNSTREAM_PORT_ASSOCIATION_STRUCTURE;
+
#pragma pack()
#endif
diff --git a/MdePkg/Include/IndustryStandard/Cxl31.h b/MdePkg/Include/IndustryStandard/Cxl31.h
new file mode 100644
index 000000000000..a94bf597b563
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Cxl31.h
@@ -0,0 +1,47 @@
+/** @file
+ CXL 3.1 definitions
+
+ This file contains the register definitions and firmware interface based
+ on the Compute Express Link (CXL) Specification Revision 3.1.
+
+ Copyright (c) 2024, Phytium Technology Co Ltd. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Compute Express Link (CXL) Specification Revision 3.1.
+ (https://computeexpresslink.org/cxl-specification/)
+
+**/
+
+#ifndef CXL31_H_
+#define CXL31_H_
+
+#include <IndustryStandard/Cxl30.h>
+
+//
+// "CEDT" CXL Early Discovery Table
+// Compute Express Link Specification Revision 3.1 - Chapter 9.18.1
+//
+#define CXL_EARLY_DISCOVERY_TABLE_REVISION_02 0x2
+
+#define CEDT_TYPE_CSDS 0x4
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+//
+// Definition for CXL System Description Structure (CSDS)
+// Compute Express Link Specification Revision 3.1 - Chapter 9.18.6
+//
+typedef struct {
+ CEDT_STRUCTURE Header;
+ UINT16 Capabilities;
+ UINT16 Reserved;
+} CXL_DOWNSTREAM_PORT_ASSOCIATION_STRUCTURE;
+
+#pragma pack()
+
+#endif
diff --git a/MdePkg/Include/IndustryStandard/IpmiSerial.h b/MdePkg/Include/IndustryStandard/IpmiSerial.h
new file mode 100644
index 000000000000..09366ee7da08
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/IpmiSerial.h
@@ -0,0 +1,66 @@
+/** @file
+ IPMI Serial Definitions
+
+ Copyright (c) 2024, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ - IPMI Specification
+ Version 2.0, Rev. 1.1
+
+ https://www.intel.com/content/www/us/en/products/docs/servers/ipmi/ipmi-second-gen-interface-spec-v2-rev1-1.html
+**/
+
+#ifndef IPMI_SERIAL_H_
+#define IPMI_SERIAL_H_
+
+///
+/// IPMI Serial Escaped Character Definition
+/// Section 14.4.1 & 14.4.2
+///
+#define BASIC_MODE_START 0xA0
+#define BASIC_MODE_STOP 0xA5
+#define BASIC_MODE_HANDSHAKE 0xA6
+#define BASIC_MODE_ESCAPE 0xAA
+#define BASIC_MODE_ESC_CHAR 0x1B
+#define BASIC_MODE_START_ENCODED_BYTE 0xB0
+#define BASIC_MODE_STOP_ENCODED_BYTE 0xB5
+#define BASIC_MODE_HANDSHAKE_ENCODED_BYTE 0xB6
+#define BASIC_MODE_ESCAPE_ENCODED_BYTE 0xBA
+#define BASIC_MODE_ESC_CHAR_ENCODED_BYTE 0x3B
+
+///
+/// IPMI Serial State Machine
+///
+#define MSG_IDLE 0
+#define MSG_IN_PROGRESS 1
+
+///
+/// IPMI Serial Message Field Definition
+/// Section 14.4.3
+///
+#define IPMI_MAX_LUN 0x3
+#define IPMI_MAX_NETFUNCTION 0x3F
+#define IPMI_SERIAL_CONNECTION_HEADER_LENGTH 3
+#define IPMI_SERIAL_REQUEST_DATA_HEADER_LENGTH 3
+#define IPMI_SERIAL_MAXIMUM_PACKET_SIZE_IN_BYTES 256
+#define IPMI_SERIAL_MIN_REQUEST_LENGTH 7
+
+#pragma pack (1)
+///
+/// IPMI Serial Message Field
+/// Section 14.4.3
+///
+typedef struct {
+ UINT8 ResponderAddress;
+ UINT8 ResponderNetFnLun;
+ UINT8 CheckSum;
+ UINT8 RequesterAddress;
+ UINT8 RequesterSeqLun;
+ UINT8 Command;
+ UINT8 Data[];
+} IPMI_SERIAL_HEADER;
+
+#pragma pack ()
+
+#endif /* IPMI_SERIAL_H_ */
diff --git a/MdePkg/Include/IndustryStandard/ServiceProcessorManagementInterfaceTable.h b/MdePkg/Include/IndustryStandard/ServiceProcessorManagementInterfaceTable.h
index 8886a7174b46..8886a7174b46 100644..100755
--- a/MdePkg/Include/IndustryStandard/ServiceProcessorManagementInterfaceTable.h
+++ b/MdePkg/Include/IndustryStandard/ServiceProcessorManagementInterfaceTable.h
diff --git a/MdePkg/Include/IndustryStandard/Tpm12.h b/MdePkg/Include/IndustryStandard/Tpm12.h
index 031b206740ed..13395ed3d599 100644
--- a/MdePkg/Include/IndustryStandard/Tpm12.h
+++ b/MdePkg/Include/IndustryStandard/Tpm12.h
@@ -744,8 +744,8 @@ typedef struct tdTPM_PERMANENT_FLAGS {
BOOLEAN TPMpost;
BOOLEAN TPMpostLock;
BOOLEAN FIPS;
- BOOLEAN operator;
- BOOLEAN enableRevokeEK;
+ BOOLEAN operator_;
+ BOOLEAN enableRevokeEK;
BOOLEAN nvLocked;
BOOLEAN readSRKPub;
BOOLEAN tpmEstablished;
diff --git a/MdePkg/Include/IndustryStandard/Tpm20.h b/MdePkg/Include/IndustryStandard/Tpm20.h
index 78e6c7094fe1..637aa3d5036a 100644
--- a/MdePkg/Include/IndustryStandard/Tpm20.h
+++ b/MdePkg/Include/IndustryStandard/Tpm20.h
@@ -1248,7 +1248,7 @@ typedef union {
TPMI_AES_KEY_BITS aes;
TPMI_SM4_KEY_BITS SM4;
TPM_KEY_BITS sym;
- TPMI_ALG_HASH xor;
+ TPMI_ALG_HASH xor_;
} TPMU_SYM_KEY_BITS;
// Table 123 - TPMU_SYM_MODE Union
@@ -1321,7 +1321,7 @@ typedef struct {
// Table 136 - TPMU_SCHEME_KEYEDHASH Union
typedef union {
TPMS_SCHEME_HMAC hmac;
- TPMS_SCHEME_XOR xor;
+ TPMS_SCHEME_XOR xor_;
} TPMU_SCHEME_KEYEDHASH;
// Table 137 - TPMT_KEYEDHASH_SCHEME Structure
diff --git a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
index 10a6190ee037..4ef570284479 100644
--- a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
+++ b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
@@ -17,9 +17,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define EFI_TPM2_ACPI_TABLE_REVISION_3 3
#define EFI_TPM2_ACPI_TABLE_REVISION_4 4
+#define EFI_TPM2_ACPI_TABLE_REVISION_5 5
#define EFI_TPM2_ACPI_TABLE_REVISION EFI_TPM2_ACPI_TABLE_REVISION_4
#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 12
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_5 16
#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4
typedef struct {
@@ -40,6 +42,7 @@ typedef struct {
#define EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE 7
#define EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_ACPI 8
#define EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_SMC 11
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_FFA 15
typedef struct {
UINT32 Reserved;
diff --git a/MdePkg/Include/IndustryStandard/Ufs.h b/MdePkg/Include/IndustryStandard/Ufs.h
new file mode 100644
index 000000000000..dac2fd9b78e7
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Ufs.h
@@ -0,0 +1,1022 @@
+/*++ @file
+
+ Common definitions for Universal Flash Storage (UFS)
+
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ JESD220 - Universal Flash Storage (UFS)
+ Version 4.0
+ https://www.jedec.org/system/files/docs/JESD220F.pdf
+--*/
+
+#ifndef __UFS_H__
+#define __UFS_H__
+
+#include <Base.h>
+
+#define UFS_LUN_0 0x00
+#define UFS_LUN_1 0x01
+#define UFS_LUN_2 0x02
+#define UFS_LUN_3 0x03
+#define UFS_LUN_4 0x04
+#define UFS_LUN_5 0x05
+#define UFS_LUN_6 0x06
+#define UFS_LUN_7 0x07
+#define UFS_WLUN_REPORT_LUNS 0x81
+#define UFS_WLUN_UFS_DEV 0xD0
+#define UFS_WLUN_BOOT 0xB0
+#define UFS_WLUN_RPMB 0xC4
+
+#pragma pack(1)
+
+//
+// UFS 4.0 Spec Table 10.13 - UTP Command UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x01*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 CmdSet : 4; /* Command Set Type */
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd1;
+ UINT8 Rsvd2;
+ UINT8 Rsvd3 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3
+ //
+ UINT32 ExpDataTranLen; /* Expected Data Transfer Length - Big Endian */
+
+ //
+ // DW4 - DW7
+ //
+ UINT8 Cdb[16];
+} UTP_COMMAND_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.15 - UTP Response UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x21*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 CmdSet : 4; /* Command Set Type */
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd1 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+ UINT8 Response; /* Response */
+ UINT8 Status; /* Status */
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 DevInfo; /* Device Information */
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian */
+
+ //
+ // DW3
+ //
+ UINT32 ResTranCount; /* Residual Transfer Count - Big Endian */
+
+ //
+ // DW4 - DW7
+ //
+ UINT8 Rsvd2[16];
+
+ //
+ // Data Segment - Sense Data
+ //
+ UINT16 SenseDataLen; /* Sense Data Length - Big Endian */
+ UINT8 SenseData[18]; /* Sense Data */
+} UTP_RESPONSE_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.21 - UTP Data-Out UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x02*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd2[2];
+ UINT8 Rsvd3 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian */
+
+ //
+ // DW3
+ //
+ UINT32 DataBufOffset; /* Data Buffer Offset - Big Endian */
+
+ //
+ // DW4
+ //
+ UINT32 DataTranCount; /* Data Transfer Count - Big Endian */
+
+ //
+ // DW5 - DW7
+ //
+ UINT8 Rsvd5[12];
+
+ //
+ // Data Segment - Data to be sent out
+ //
+ // UINT8 Data[]; /* Data to be sent out, maximum is 65535 bytes */
+} UTP_DATA_OUT_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.23 - UTP Data-In UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x22*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd2 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+ UINT8 Rsvd3[2];
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian */
+
+ //
+ // DW3
+ //
+ UINT32 DataBufOffset; /* Data Buffer Offset - Big Endian */
+
+ //
+ // DW4
+ //
+ UINT32 DataTranCount; /* Data Transfer Count - Big Endian */
+
+ //
+ // DW5
+ //
+ UINT8 HintControl : 4; /* Hint Control */
+ UINT8 Rsvd5 : 4;
+ UINT8 HintIid : 4; /* Hint Initiator ID */
+ UINT8 HintExt_Iid : 4; /* Hint Initiator ID Extended */
+ UINT8 HintLun; /* Hint LUN */
+ UINT8 HintTaskTag; /* Hint Task Tag */
+
+ //
+ // DW6
+ //
+ UINT32 HintDataBufOffset; /* Hint Data Buffer Offset - Big Endian */
+
+ //
+ // DW7
+ //
+ UINT32 HintDataCount; /* Hint Data Count - Big Endian */
+
+ //
+ // Data Segment - Data to be read
+ //
+ // UINT8 Data[]; /* Data to be read, maximum is 65535 bytes */
+} UTP_DATA_IN_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.25 - UTP Ready-To-Transfer UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x31*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd2 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+ UINT8 Rsvd3[2];
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3
+ //
+ UINT32 DataBufOffset; /* Data Buffer Offset - Big Endian */
+
+ //
+ // DW4
+ //
+ UINT32 DataTranCount; /* Data Transfer Count - Big Endian */
+
+ //
+ // DW5
+ //
+ UINT8 HintControl : 4; /* Hint Control */
+ UINT8 Rsvd5 : 4;
+ UINT8 HintIid : 4; /* Hint Initiator ID */
+ UINT8 HintExt_Iid : 4; /* Hint Initiator ID Extended */
+ UINT8 HintLun; /* Hint LUN */
+ UINT8 HintTaskTag; /* Hint Task Tag */
+
+ //
+ // DW6
+ //
+ UINT32 HintDataBufOffset; /* Hint Data Buffer Offset - Big Endian */
+
+ //
+ // DW7
+ //
+ UINT32 HintDataCount; /* Hint Data Count - Big Endian */
+
+ //
+ // Data Segment - Data to be read
+ //
+ // UINT8 Data[]; /* Data to be read, maximum is 65535 bytes */
+} UTP_RDY_TO_TRAN_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.27 - UTP Task Management Request UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x04*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 TskManFunc; /* Task Management Function */
+ UINT8 Rsvd2;
+ UINT8 Rsvd3 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3
+ //
+ UINT32 InputParam1; /* Input Parameter 1 - Big Endian */
+
+ //
+ // DW4
+ //
+ UINT32 InputParam2; /* Input Parameter 2 - Big Endian */
+
+ //
+ // DW5
+ //
+ UINT32 InputParam3; /* Input Parameter 3 - Big Endian */
+
+ //
+ // DW6 - DW7
+ //
+ UINT8 Rsvd5[8];
+} UTP_TM_REQ_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.30 - UTP Task Management Response UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x24*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd2 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+ UINT8 Resp; /* Response */
+ UINT8 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3
+ //
+ UINT32 OutputParam1; /* Output Parameter 1 - Big Endian */
+
+ //
+ // DW4
+ //
+ UINT32 OutputParam2; /* Output Parameter 2 - Big Endian */
+
+ //
+ // DW5 - DW7
+ //
+ UINT8 Rsvd5[12];
+} UTP_TM_RESP_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.35 - 10.57 - Transaction Specific Fields for (Genericized) Opcode
+//
+typedef struct {
+ UINT8 Opcode;
+ UINT8 DescId;
+ UINT8 Index;
+ UINT8 Selector;
+ UINT16 Rsvd1;
+ UINT16 Length;
+ UINT32 Value;
+ UINT32 Rsvd2;
+} UTP_UPIU_TSF;
+
+//
+// UFS 4.0 Spec Table 10.33 - UTP Query Request UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x16*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Rsvd1;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd2;
+ UINT8 QueryFunc; /* Query Function */
+ UINT8 Rsvd3[2];
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd4;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian */
+
+ //
+ // DW3 - 6
+ //
+ UTP_UPIU_TSF Tsf; /* Transaction Specific Fields */
+
+ //
+ // DW7
+ //
+ UINT8 Rsvd5[4];
+
+ //
+ // Data Segment - Data to be transferred
+ //
+ // UINT8 Data[]; /* Data to be transferred, maximum is 65535 bytes */
+} UTP_QUERY_REQ_UPIU;
+
+#define QUERY_FUNC_STD_READ_REQ 0x01
+#define QUERY_FUNC_STD_WRITE_REQ 0x81
+
+//
+// UFS 4.0 Spec Table 10.36 - Query Function opcode values
+//
+typedef enum {
+ UtpQueryFuncOpcodeNop = 0x00,
+ UtpQueryFuncOpcodeRdDesc = 0x01,
+ UtpQueryFuncOpcodeWrDesc = 0x02,
+ UtpQueryFuncOpcodeRdAttr = 0x03,
+ UtpQueryFuncOpcodeWrAttr = 0x04,
+ UtpQueryFuncOpcodeRdFlag = 0x05,
+ UtpQueryFuncOpcodeSetFlag = 0x06,
+ UtpQueryFuncOpcodeClrFlag = 0x07,
+ UtpQueryFuncOpcodeTogFlag = 0x08
+} UTP_QUERY_FUNC_OPCODE;
+
+//
+// UFS 4.0 Spec Table 10.46 - UTP Query Response UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x36*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Rsvd1;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd2;
+ UINT8 QueryFunc; /* Query Function */
+ UINT8 QueryResp; /* Query Response */
+ UINT8 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 DevInfo; /* Device Information */
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian */
+
+ //
+ // DW3 - 6
+ //
+ UTP_UPIU_TSF Tsf; /* Transaction Specific Fields */
+
+ //
+ // DW7
+ //
+ UINT8 Rsvd4[4];
+
+ //
+ // Data Segment - Data to be transferred
+ //
+ // UINT8 Data[]; /* Data to be transferred, maximum is 65535 bytes */
+} UTP_QUERY_RESP_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.47 - Query Response Code
+//
+typedef enum {
+ UfsUtpQueryResponseSuccess = 0x00,
+ UfsUtpQueryResponseParamNotReadable = 0xF6,
+ UfsUtpQueryResponseParamNotWriteable = 0xF7,
+ UfsUtpQueryResponseParamAlreadyWritten = 0xF8,
+ UfsUtpQueryResponseInvalidLen = 0xF9,
+ UfsUtpQueryResponseInvalidVal = 0xFA,
+ UfsUtpQueryResponseInvalidSelector = 0xFB,
+ UfsUtpQueryResponseInvalidIndex = 0xFC,
+ UfsUtpQueryResponseInvalidIdn = 0xFD,
+ UfsUtpQueryResponseInvalidOpc = 0xFE,
+ UfsUtpQueryResponseGeneralFailure = 0xFF
+} UTP_QUERY_RESP_CODE;
+
+//
+// UFS 4.0 Spec Table 10.58 - UTP Reject UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x3F*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Lun;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd1 : 4;
+ UINT8 Iid : 4; /* Initiator ID */
+ UINT8 Rsvd2 : 4;
+ UINT8 Ext_Iid : 4; /* Initiator ID Extended */
+ UINT8 Response; /* Response - 0x01 */
+ UINT8 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 DevInfo; /* Device Information - 0x00 */
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3
+ //
+ UINT8 HdrSts; /* Basic Header Status */
+ UINT8 Rsvd4;
+ UINT8 E2ESts; /* End-to-End Status */
+ UINT8 Rsvd5;
+
+ //
+ // DW4 - DW7
+ //
+ UINT8 Rsvd6[16];
+} UTP_REJ_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.61 - UTP NOP OUT UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x00*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Rsvd1;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd2[4];
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 Rsvd3;
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3 - DW7
+ //
+ UINT8 Rsvd4[20];
+} UTP_NOP_OUT_UPIU;
+
+//
+// UFS 4.0 Spec Table 10.62 - UTP NOP IN UPIU
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT8 TransCode : 6; /* Transaction Type - 0x20*/
+ UINT8 Dd : 1;
+ UINT8 Hd : 1;
+ UINT8 Flags;
+ UINT8 Rsvd1;
+ UINT8 TaskTag; /* Task Tag */
+
+ //
+ // DW1
+ //
+ UINT8 Rsvd2[2];
+ UINT8 Resp; /* Response - 0x00 */
+ UINT8 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT8 EhsLen; /* Total EHS Length - 0x00 */
+ UINT8 DevInfo; /* Device Information - 0x00 */
+ UINT16 DataSegLen; /* Data Segment Length - Big Endian - 0x0000 */
+
+ //
+ // DW3 - DW7
+ //
+ UINT8 Rsvd4[20];
+} UTP_NOP_IN_UPIU;
+
+//
+// UFS 4.0 Spec Table 14.1 - Descriptor identification values
+//
+typedef enum {
+ UfsDeviceDesc = 0x00,
+ UfsConfigDesc = 0x01,
+ UfsUnitDesc = 0x02,
+ UfsInterConnDesc = 0x04,
+ UfsStringDesc = 0x05,
+ UfsGeometryDesc = 0x07,
+ UfsPowerDesc = 0x08,
+ UfsDevHealthDesc = 0x09
+} UFS_DESC_IDN;
+
+//
+// UFS 4.0 Spec Table 14.4 - Device Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 Device;
+ UINT8 DevClass;
+ UINT8 DevSubClass;
+ UINT8 Protocol;
+ UINT8 NumLun;
+ UINT8 NumWLun;
+ UINT8 BootEn;
+ UINT8 DescAccessEn;
+ UINT8 InitPowerMode;
+ UINT8 HighPriorityLun;
+ UINT8 SecureRemovalType;
+ UINT8 SecurityLun;
+ UINT8 BgOpsTermLat;
+ UINT8 InitActiveIccLevel;
+ UINT16 SpecVersion;
+ UINT16 ManufactureDate;
+ UINT8 ManufacturerName;
+ UINT8 ProductName;
+ UINT8 SerialName;
+ UINT8 OemId;
+ UINT16 ManufacturerId;
+ UINT8 Ud0BaseOffset;
+ UINT8 Ud0ConfParamLen;
+ UINT8 DevRttCap;
+ UINT16 PeriodicRtcUpdate;
+ UINT8 UFSFeaturesSupport; // Deprecated, use ExtendedUFSFeaturesSupport
+ UINT8 FFUTimeout;
+ UINT8 QueueDepth;
+ UINT16 DeviceVersion;
+ UINT8 NumSecureWPArea;
+ UINT32 PSAMaxDataSize;
+ UINT8 PSAStateTimeout;
+ UINT8 ProductRevisionLevel;
+ UINT8 Rsvd1[5];
+ UINT8 Rsvd2[16];
+ UINT8 Rsvd3[3];
+ UINT8 Rsvd4[12];
+ UINT32 ExtendedUFSFeaturesSupport;
+ UINT8 WriteBoosterBufPreserveUserSpaceEn;
+ UINT8 WriteBoosterBufType;
+ UINT32 NumSharedWriteBoosterAllocUnits;
+} UFS_DEV_DESC;
+
+//
+// UFS 4.0 Spec Table 14.4 (Offset 10h) - Specification version
+//
+typedef union {
+ struct {
+ UINT8 Suffix : 4;
+ UINT8 Minor : 4;
+ UINT8 Major;
+ } Bits;
+ UINT16 Data;
+} UFS_SPEC_VERSION;
+
+//
+// UFS 4.0 Spec Table 14.4 (Offset 4Fh) - Extended UFS Features Support
+//
+typedef union {
+ struct {
+ UINT32 FFU : 1;
+ UINT32 PSA : 1;
+ UINT32 DeviceLifeSpan : 1;
+ UINT32 RefreshOperation : 1;
+ UINT32 TooHighTemp : 1;
+ UINT32 TooLowTemp : 1;
+ UINT32 ExtendedTemp : 1;
+ UINT32 Rsvd1 : 1;
+ UINT32 WriteBooster : 1;
+ UINT32 PerformanceThrottling : 1;
+ UINT32 AdvancedRPMB : 1;
+ UINT32 Rsvd2 : 3;
+ UINT32 Barrier : 1;
+ UINT32 ClearErrorHistory : 1;
+ UINT32 Ext_Iid : 1;
+ UINT32 Rsvd3 : 1;
+ UINT32 Rsvd4 : 14;
+ } Bits;
+ UINT32 Data;
+} EXTENDED_UFS_FEATURES_SUPPORT;
+
+//
+// UFS 4.0 Spec Table 14.10 - Configuration Descriptor Header (INDEX = 0)
+// and Device Descriptor Configuration parameters
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 ConfDescContinue;
+ UINT8 BootEn;
+ UINT8 DescAccessEn;
+ UINT8 InitPowerMode;
+ UINT8 HighPriorityLun;
+ UINT8 SecureRemovalType;
+ UINT8 InitActiveIccLevel;
+ UINT16 PeriodicRtcUpdate;
+ UINT8 Rsvd1;
+ UINT8 RpmbRegionEnable;
+ UINT8 RpmbRegion1Size;
+ UINT8 RpmbRegion2Size;
+ UINT8 RpmbRegion3Size;
+ UINT8 WriteBoosterBufPreserveUserSpaceEn;
+ UINT8 WriteBoosterBufType;
+ UINT32 NumSharedWriteBoosterAllocUnits;
+} UFS_CONFIG_DESC_GEN_HEADER;
+
+//
+// UFS 4.0 Spec Table 14.11 - Configuration Descriptor Header (INDEX = 1/2/3)
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 ConfDescContinue;
+ UINT8 Rsvd1[19];
+} UFS_CONFIG_DESC_EXT_HEADER;
+
+//
+// UFS 4.0 Spec Table 14.12 - UNit Descriptor configurable parameters
+//
+typedef struct {
+ UINT8 LunEn;
+ UINT8 BootLunId;
+ UINT8 LunWriteProt;
+ UINT8 MemType;
+ UINT32 NumAllocUnits;
+ UINT8 DataReliability;
+ UINT8 LogicBlkSize;
+ UINT8 ProvisionType;
+ UINT16 CtxCap;
+ UINT8 Rsvd1[3];
+ UINT8 Rsvd2[6];
+ UINT32 LuNumWriteBoosterBufAllocUnits;
+} UFS_UNIT_DESC_CONFIG_PARAMS;
+
+//
+// UFS 4.0 Spec Table 14.6 - Configuration Descriptor Format
+//
+// WARNING: This struct contains variable-size members! (across spec versions)
+// To maintain backward compatibility, UnitDescConfParams should not be
+// accessed as a struct member.
+// Instead, use `Ud0BaseOffset` and `Ud0ConfParamLen` from the Device
+// Descriptor to calculate the offset and location of the Unit Descriptors.
+//
+typedef struct {
+ UFS_CONFIG_DESC_GEN_HEADER Header;
+ UFS_UNIT_DESC_CONFIG_PARAMS UnitDescConfParams[8];
+} UFS_CONFIG_DESC;
+
+//
+// UFS 4.0 Spec Table 14.13 - Geometry Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 MediaTech;
+ UINT8 Rsvd1;
+ UINT64 TotalRawDevCapacity;
+ UINT8 MaxNumberLu;
+ UINT32 SegSize;
+ UINT8 AllocUnitSize;
+ UINT8 MinAddrBlkSize;
+ UINT8 OptReadBlkSize;
+ UINT8 OptWriteBlkSize;
+ UINT8 MaxInBufSize;
+ UINT8 MaxOutBufSize;
+ UINT8 RpmbRwSize;
+ UINT8 DynamicCapacityResourcePolicy;
+ UINT8 DataOrder;
+ UINT8 MaxCtxIdNum;
+ UINT8 SysDataTagUnitSize;
+ UINT8 SysDataResUnitSize;
+ UINT8 SupSecRemovalTypes;
+ UINT16 SupMemTypes;
+ UINT32 SysCodeMaxNumAllocUnits;
+ UINT16 SupCodeCapAdjFac;
+ UINT32 NonPersMaxNumAllocUnits;
+ UINT16 NonPersCapAdjFac;
+ UINT32 Enhance1MaxNumAllocUnits;
+ UINT16 Enhance1CapAdjFac;
+ UINT32 Enhance2MaxNumAllocUnits;
+ UINT16 Enhance2CapAdjFac;
+ UINT32 Enhance3MaxNumAllocUnits;
+ UINT16 Enhance3CapAdjFac;
+ UINT32 Enhance4MaxNumAllocUnits;
+ UINT16 Enhance4CapAdjFac;
+ UINT32 OptLogicBlkSize;
+ UINT8 Rsvd2[5];
+ UINT8 Rsvd3[2];
+ UINT32 WriteBoosterBufMaxNumAllocUnits;
+ UINT8 DeviceMaxWriteBoosterLus;
+ UINT8 WriteBoosterBufCapAdjFac;
+ UINT8 SupWriteBoosterBufUserSpaceReductionTypes;
+ UINT8 SupWriteBoosterBufTypes;
+} UFS_GEOMETRY_DESC;
+
+//
+// UFS 4.0 Spec Table 14.14 - Unit Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 UnitIdx;
+ UINT8 LunEn;
+ UINT8 BootLunId;
+ UINT8 LunWriteProt;
+ UINT8 LunQueueDep;
+ UINT8 PsaSensitive;
+ UINT8 MemType;
+ UINT8 DataReliability;
+ UINT8 LogicBlkSize;
+ UINT64 LogicBlkCount;
+ UINT32 EraseBlkSize;
+ UINT8 ProvisionType;
+ UINT64 PhyMemResCount;
+ UINT16 CtxCap;
+ UINT8 LargeUnitGranularity;
+ UINT8 Rsvd1[6];
+ UINT32 LuNumWriteBoosterBufAllocUnits;
+} UFS_UNIT_DESC;
+
+//
+// UFS 4.0 Spec Table 14.15 - RPMB Unit Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 UnitIdx;
+ UINT8 LunEn;
+ UINT8 BootLunId;
+ UINT8 LunWriteProt;
+ UINT8 LunQueueDep;
+ UINT8 PsaSensitive;
+ UINT8 MemType;
+ UINT8 RpmbRegionEnable;
+ UINT8 LogicBlkSize;
+ UINT64 LogicBlkCount;
+ UINT8 RpmbRegion0Size;
+ UINT8 RpmbRegion1Size;
+ UINT8 RpmbRegion2Size;
+ UINT8 RpmbRegion3Size;
+ UINT8 ProvisionType;
+ UINT64 PhyMemResCount;
+ UINT8 Rsvd3[3];
+} UFS_RPMB_UNIT_DESC;
+
+//
+// UFS 4.0 Spec Table 7.13 - Format for Power Parameter element
+//
+typedef struct {
+ UINT16 Value : 12;
+ UINT16 Rsvd1 : 2;
+ UINT16 Unit : 2;
+} UFS_POWER_PARAM_ELEMENT;
+
+//
+// UFS 4.0 Spec Table 14.16 - Power Parameters Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UFS_POWER_PARAM_ELEMENT ActiveIccLevelVcc[16];
+ UFS_POWER_PARAM_ELEMENT ActiveIccLevelVccQ[16];
+ UFS_POWER_PARAM_ELEMENT ActiveIccLevelVccQ2[16];
+} UFS_POWER_DESC;
+
+//
+// UFS 4.0 Spec Table 14.17 - Interconnect Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT16 UniProVer;
+ UINT16 MphyVer;
+} UFS_INTER_CONNECT_DESC;
+
+//
+// UFS 4.0 Spec Table 14.18 - 14.22 - String Descriptor
+//
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ CHAR16 Unicode[126];
+} UFS_STRING_DESC;
+
+//
+// UFS 4.0 Spec Table 14.26 - Flags
+//
+typedef enum {
+ UfsFlagDevInit = 0x01,
+ UfsFlagPermWpEn = 0x02,
+ UfsFlagPowerOnWpEn = 0x03,
+ UfsFlagBgOpsEn = 0x04,
+ UfsFlagDevLifeSpanModeEn = 0x05,
+ UfsFlagPurgeEn = 0x06,
+ UfsFlagRefreshEn = 0x07,
+ UfsFlagPhyResRemoval = 0x08,
+ UfsFlagBusyRtc = 0x09,
+ UfsFlagPermDisFwUpdate = 0x0B,
+ UfsFlagWriteBoosterEn = 0x0E,
+ UfsFlagWbBufFlushEn = 0x0F,
+ UfsFlagWbBufFlushHibernate = 0x10
+} UFS_FLAGS_IDN;
+
+//
+// UFS 4.0 Spec Table 14.28 - Attributes
+//
+typedef enum {
+ UfsAttrBootLunEn = 0x00,
+ UfsAttrCurPowerMode = 0x02,
+ UfsAttrActiveIccLevel = 0x03,
+ UfsAttrOutOfOrderDataEn = 0x04,
+ UfsAttrBgOpStatus = 0x05,
+ UfsAttrPurgeStatus = 0x06,
+ UfsAttrMaxDataInSize = 0x07,
+ UfsAttrMaxDataOutSize = 0x08,
+ UfsAttrDynCapNeeded = 0x09,
+ UfsAttrRefClkFreq = 0x0a,
+ UfsAttrConfigDescLock = 0x0b,
+ UfsAttrMaxNumOfRtt = 0x0c,
+ UfsAttrExceptionEvtCtrl = 0x0d,
+ UfsAttrExceptionEvtSts = 0x0e,
+ UfsAttrSecondsPassed = 0x0f,
+ UfsAttrContextConf = 0x10,
+ UfsAttrDeviceFfuStatus = 0x14,
+ UfsAttrPsaState = 0x15,
+ UfsAttrPsaDataSize = 0x16,
+ UfsAttrRefClkGatingWaitTime = 0x17,
+ UfsAttrDeviceCaseRoughTemp = 0x18,
+ UfsAttrDeviceTooHighTempBound = 0x19,
+ UfsAttrDeviceTooLowTempBound = 0x1a,
+ UfsAttrThrottlingStatus = 0x1b,
+ UfsAttrWriteBoosterBufFlushStatus = 0x1c,
+ UfsAttrAvailableWriteBoosterBufSize = 0x1d,
+ UfsAttrWriteBoosterBufLifeTimeEst = 0x1e,
+ UfsAttrCurrentWriteBoosterBufSize = 0x1f,
+ UfsAttrExtIidEn = 0x2a,
+ UfsAttrHostHintCacheSize = 0x2b,
+ UfsAttrRefreshStatus = 0x2c,
+ UfsAttrRefreshFreq = 0x2d,
+ UfsAttrRefreshUnit = 0x2e,
+ UfsAttrRefreshMethod = 0x2f,
+ UfsAttrTimestamp = 0x30
+} UFS_ATTR_IDN;
+
+#pragma pack()
+
+#endif
diff --git a/MdePkg/Include/IndustryStandard/UfsHci.h b/MdePkg/Include/IndustryStandard/UfsHci.h
new file mode 100644
index 000000000000..6a6c819dc6e2
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/UfsHci.h
@@ -0,0 +1,533 @@
+/*++ @file
+
+ Common definitions for UFS Host Controller Interface (UFSHCI)
+
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ JESD223 - Universal Flash Storage Host Controller Interface (UFSHCI)
+ Version 2.0
+ https://www.jedec.org/system/files/docs/JESD223C.pdf
+--*/
+
+#ifndef __UFS_HCI_H__
+#define __UFS_HCI_H__
+
+#include <Base.h>
+
+#include <IndustryStandard/Ufs.h>
+
+//
+// Host Capabilities Register Offsets
+//
+#define UFS_HC_CAP_OFFSET 0x0000 // Controller Capabilities
+#define UFS_HC_VER_OFFSET 0x0008 // Version
+#define UFS_HC_DDID_OFFSET 0x0010 // Device ID and Device Class
+#define UFS_HC_PMID_OFFSET 0x0014 // Product ID and Manufacturer ID
+#define UFS_HC_AHIT_OFFSET 0x0018 // Auto-Hibernate Idle Timer
+//
+// Operation and Runtime Register Offsets
+//
+#define UFS_HC_IS_OFFSET 0x0020 // Interrupt Status
+#define UFS_HC_IE_OFFSET 0x0024 // Interrupt Enable
+#define UFS_HC_STATUS_OFFSET 0x0030 // Host Controller Status
+#define UFS_HC_ENABLE_OFFSET 0x0034 // Host Controller Enable
+#define UFS_HC_UECPA_OFFSET 0x0038 // Host UIC Error Code PHY Adapter Layer
+#define UFS_HC_UECDL_OFFSET 0x003c // Host UIC Error Code Data Link Layer
+#define UFS_HC_UECN_OFFSET 0x0040 // Host UIC Error Code Network Layer
+#define UFS_HC_UECT_OFFSET 0x0044 // Host UIC Error Code Transport Layer
+#define UFS_HC_UECDME_OFFSET 0x0048 // Host UIC Error Code DME
+#define UFS_HC_UTRIACR_OFFSET 0x004c // UTP Transfer Request Interrupt Aggregation Control Register
+//
+// UTP Transfer Register Offsets
+//
+#define UFS_HC_UTRLBA_OFFSET 0x0050 // UTP Transfer Request List Base Address
+#define UFS_HC_UTRLBAU_OFFSET 0x0054 // UTP Transfer Request List Base Address Upper 32-Bits
+#define UFS_HC_UTRLDBR_OFFSET 0x0058 // UTP Transfer Request List Door Bell Register
+#define UFS_HC_UTRLCLR_OFFSET 0x005c // UTP Transfer Request List CLear Register
+#define UFS_HC_UTRLRSR_OFFSET 0x0060 // UTP Transfer Request Run-Stop Register
+//
+// UTP Task Management Register Offsets
+//
+#define UFS_HC_UTMRLBA_OFFSET 0x0070 // UTP Task Management Request List Base Address
+#define UFS_HC_UTMRLBAU_OFFSET 0x0074 // UTP Task Management Request List Base Address Upper 32-Bits
+#define UFS_HC_UTMRLDBR_OFFSET 0x0078 // UTP Task Management Request List Door Bell Register
+#define UFS_HC_UTMRLCLR_OFFSET 0x007c // UTP Task Management Request List CLear Register
+#define UFS_HC_UTMRLRSR_OFFSET 0x0080 // UTP Task Management Run-Stop Register
+//
+// UIC Command Register Offsets
+//
+#define UFS_HC_UIC_CMD_OFFSET 0x0090 // UIC Command Register
+#define UFS_HC_UCMD_ARG1_OFFSET 0x0094 // UIC Command Argument 1
+#define UFS_HC_UCMD_ARG2_OFFSET 0x0098 // UIC Command Argument 2
+#define UFS_HC_UCMD_ARG3_OFFSET 0x009c // UIC Command Argument 3
+//
+// UMA Register Offsets
+//
+#define UFS_HC_UMA_OFFSET 0x00b0 // Reserved for Unified Memory Extension
+
+#define UFS_HC_HCE_EN BIT0
+#define UFS_HC_HCS_DP BIT0
+#define UFS_HC_HCS_UCRDY BIT3
+#define UFS_HC_IS_ULSS BIT8
+#define UFS_HC_IS_UCCS BIT10
+#define UFS_HC_CAP_64ADDR BIT24
+#define UFS_HC_CAP_NUTMRS (BIT16 | BIT17 | BIT18)
+#define UFS_HC_CAP_NUTRS (BIT0 | BIT1 | BIT2 | BIT3 | BIT4)
+#define UFS_HC_UTMRLRSR BIT0
+#define UFS_HC_UTRLRSR BIT0
+
+//
+// The initial value of the OCS field of UTP TRD or TMRD descriptor
+// defined in JEDEC JESD223 specification
+//
+#define UFS_HC_TRD_OCS_INIT_VALUE 0x0F
+
+//
+// A maximum of length of 256KB is supported by PRDT entry
+//
+#define UFS_MAX_DATA_LEN_PER_PRD 0x40000
+
+#define UFS_STORAGE_COMMAND_TYPE 0x01
+
+#define UFS_REGULAR_COMMAND 0x00
+#define UFS_INTERRUPT_COMMAND 0x01
+
+#pragma pack(1)
+
+//
+// UFSHCI 2.0 Spec Section 5.2.1 Offset 00h: CAP - Controller Capabilities
+//
+typedef struct {
+ UINT8 Nutrs : 4; // Number of UTP Transfer Request Slots
+ UINT8 Rsvd1 : 4;
+
+ UINT8 NoRtt; // Number of outstanding READY TO TRANSFER (RTT) requests supported
+
+ UINT8 Nutmrs : 3; // Number of UTP Task Management Request Slots
+ UINT8 Rsvd2 : 4;
+ UINT8 AutoHs : 1; // Auto-Hibernation Support
+
+ UINT8 As64 : 1; // 64-bit addressing supported
+ UINT8 Oodds : 1; // Out of order data delivery supported
+ UINT8 UicDmetms : 1; // UIC DME_TEST_MODE command supported
+ UINT8 Ume : 1; // Reserved for Unified Memory Extension
+ UINT8 Rsvd4 : 4;
+} UFS_HC_CAP;
+
+//
+// UFSHCI 2.0 Spec Section 5.2.2 Offset 08h: VER - UFS Version
+//
+typedef struct {
+ UINT8 Vs : 4; // Version Suffix
+ UINT8 Mnr : 4; // Minor version number
+
+ UINT8 Mjr; // Major version number
+
+ UINT16 Rsvd1;
+} UFS_HC_VER;
+
+//
+// UFSHCI 2.0 Spec Section 5.2.3 Offset 10h: HCPID - Host Controller Product ID
+//
+#define UFS_HC_PID UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.2.4 Offset 14h: HCMID - Host Controller Manufacturer ID
+//
+#define UFS_HC_MID UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.2.5 Offset 18h: AHIT - Auto-Hibernate Idle Timer
+//
+typedef struct {
+ UINT32 Ahitv : 10; // Auto-Hibernate Idle Timer Value
+ UINT32 Ts : 3; // Timer scale
+ UINT32 Rsvd1 : 19;
+} UFS_HC_AHIT;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.1 Offset 20h: IS - Interrupt Status
+//
+typedef struct {
+ UINT16 Utrcs : 1; // UTP Transfer Request Completion Status
+ UINT16 Udepri : 1; // UIC DME_ENDPOINT_RESET Indication
+ UINT16 Ue : 1; // UIC Error
+ UINT16 Utms : 1; // UIC Test Mode Status
+
+ UINT16 Upms : 1; // UIC Power Mode Status
+ UINT16 Uhxs : 1; // UIC Hibernate Exit Status
+ UINT16 Uhes : 1; // UIC Hibernate Enter Status
+ UINT16 Ulls : 1; // UIC Link Lost Status
+
+ UINT16 Ulss : 1; // UIC Link Startup Status
+ UINT16 Utmrcs : 1; // UTP Task Management Request Completion Status
+ UINT16 Uccs : 1; // UIC Command Completion Status
+ UINT16 Dfes : 1; // Device Fatal Error Status
+
+ UINT16 Utpes : 1; // UTP Error Status
+ UINT16 Rsvd1 : 3;
+
+ UINT16 Hcfes : 1; // Host Controller Fatal Error Status
+ UINT16 Sbfes : 1; // System Bus Fatal Error Status
+ UINT16 Rsvd2 : 14;
+} UFS_HC_IS;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.2 Offset 24h: IE - Interrupt Enable
+//
+typedef struct {
+ UINT16 Utrce : 1; // UTP Transfer Request Completion Enable
+ UINT16 Udeprie : 1; // UIC DME_ENDPOINT_RESET Enable
+ UINT16 Uee : 1; // UIC Error Enable
+ UINT16 Utmse : 1; // UIC Test Mode Status Enable
+
+ UINT16 Upmse : 1; // UIC Power Mode Status Enable
+ UINT16 Uhxse : 1; // UIC Hibernate Exit Status Enable
+ UINT16 Uhese : 1; // UIC Hibernate Enter Status Enable
+ UINT16 Ullse : 1; // UIC Link Lost Status Enable
+
+ UINT16 Ulsse : 1; // UIC Link Startup Status Enable
+ UINT16 Utmrce : 1; // UTP Task Management Request Completion Enable
+ UINT16 Ucce : 1; // UIC Command Completion Enable
+ UINT16 Dfee : 1; // Device Fatal Error Enable
+
+ UINT16 Utpee : 1; // UTP Error Enable
+ UINT16 Rsvd1 : 3;
+
+ UINT16 Hcfee : 1; // Host Controller Fatal Error Enable
+ UINT16 Sbfee : 1; // System Bus Fatal Error Enable
+ UINT16 Rsvd2 : 14;
+} UFS_HC_IE;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.3 Offset 30h: HCS - Host Controller Status
+//
+typedef struct {
+ UINT8 Dp : 1; // Device Present
+ UINT8 UtrlRdy : 1; // UTP Transfer Request List Ready
+ UINT8 UtmrlRdy : 1; // UTP Task Management Request List Ready
+ UINT8 UcRdy : 1; // UIC COMMAND Ready
+ UINT8 Rsvd1 : 4;
+
+ UINT8 Upmcrs : 3; // UIC Power Mode Change Request Status
+ UINT8 Rsvd2 : 1; // UIC Hibernate Exit Status Enable
+ UINT8 Utpec : 4; // UTP Error Code
+
+ UINT8 TtagUtpE; // Task Tag of UTP error
+ UINT8 TlunUtpE; // Target LUN of UTP error
+} UFS_HC_STATUS;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.4 Offset 34h: HCE - Host Controller Enable
+//
+typedef struct {
+ UINT32 Hce : 1; // Host Controller Enable
+ UINT32 Rsvd1 : 31;
+} UFS_HC_ENABLE;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.5 Offset 38h: UECPA - Host UIC Error Code PHY Adapter Layer
+//
+typedef struct {
+ UINT32 Ec : 5; // UIC PHY Adapter Layer Error Code
+ UINT32 Rsvd1 : 26;
+ UINT32 Err : 1; // UIC PHY Adapter Layer Error
+} UFS_HC_UECPA;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.6 Offset 3ch: UECDL - Host UIC Error Code Data Link Layer
+//
+typedef struct {
+ UINT32 Ec : 15; // UIC Data Link Layer Error Code
+ UINT32 Rsvd1 : 16;
+ UINT32 Err : 1; // UIC Data Link Layer Error
+} UFS_HC_UECDL;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.7 Offset 40h: UECN - Host UIC Error Code Network Layer
+//
+typedef struct {
+ UINT32 Ec : 3; // UIC Network Layer Error Code
+ UINT32 Rsvd1 : 28;
+ UINT32 Err : 1; // UIC Network Layer Error
+} UFS_HC_UECN;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.8 Offset 44h: UECT - Host UIC Error Code Transport Layer
+//
+typedef struct {
+ UINT32 Ec : 7; // UIC Transport Layer Error Code
+ UINT32 Rsvd1 : 24;
+ UINT32 Err : 1; // UIC Transport Layer Error
+} UFS_HC_UECT;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.9 Offset 48h: UECDME - Host UIC Error Code
+//
+typedef struct {
+ UINT32 Ec : 1; // UIC DME Error Code
+ UINT32 Rsvd1 : 30;
+ UINT32 Err : 1; // UIC DME Error
+} UFS_HC_UECDME;
+
+//
+// UFSHCI 2.0 Spec Section 5.3.10 Offset 4Ch: UTRIACR - UTP Transfer Request Interrupt Aggregation Control Register
+//
+typedef struct {
+ UINT8 IaToVal; // Interrupt aggregation timeout value
+
+ UINT8 IacTh : 5; // Interrupt aggregation counter threshold
+ UINT8 Rsvd1 : 3;
+
+ UINT8 Ctr : 1; // Counter and Timer Reset
+ UINT8 Rsvd2 : 3;
+ UINT8 Iasb : 1; // Interrupt aggregation status bit
+ UINT8 Rsvd3 : 3;
+
+ UINT8 IapwEn : 1; // Interrupt aggregation parameter write enable
+ UINT8 Rsvd4 : 6;
+ UINT8 IaEn : 1; // Interrupt Aggregation Enable/Disable
+} UFS_HC_UTRIACR;
+
+//
+// UFSHCI 2.0 Spec Section 5.4.1 Offset 50h: UTRLBA - UTP Transfer Request List Base Address
+//
+typedef struct {
+ UINT32 Rsvd1 : 10;
+ UINT32 UtrlBa : 22; // UTP Transfer Request List Base Address
+} UFS_HC_UTRLBA;
+
+//
+// UFSHCI 2.0 Spec Section 5.4.2 Offset 54h: UTRLBAU - UTP Transfer Request List Base Address Upper 32-bits
+//
+#define UFS_HC_UTRLBAU UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.4.3 Offset 58h: UTRLDBR - UTP Transfer Request List Door Bell Register
+//
+#define UFS_HC_UTRLDBR UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.4.4 Offset 5Ch: UTRLCLR - UTP Transfer Request List CLear Register
+//
+#define UFS_HC_UTRLCLR UINT32
+
+#if 0
+//
+// UFSHCI 2.0 Spec Section 5.4.5 Offset 60h: UTRLRSR - UTP Transfer Request List Run Stop Register
+//
+typedef struct {
+ UINT32 UtrlRsr : 1; // UTP Transfer Request List Run-Stop Register
+ UINT32 Rsvd1 : 31;
+} UFS_HC_UTRLRSR;
+#endif
+
+//
+// UFSHCI 2.0 Spec Section 5.5.1 Offset 70h: UTMRLBA - UTP Task Management Request List Base Address
+//
+typedef struct {
+ UINT32 Rsvd1 : 10;
+ UINT32 UtmrlBa : 22; // UTP Task Management Request List Base Address
+} UFS_HC_UTMRLBA;
+
+//
+// UFSHCI 2.0 Spec Section 5.5.2 Offset 74h: UTMRLBAU - UTP Task Management Request List Base Address Upper 32-bits
+//
+#define UFS_HC_UTMRLBAU UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.5.3 Offset 78h: UTMRLDBR - UTP Task Management Request List Door Bell Register
+//
+typedef struct {
+ UINT32 UtmrlDbr : 8; // UTP Task Management Request List Door bell Register
+ UINT32 Rsvd1 : 24;
+} UFS_HC_UTMRLDBR;
+
+//
+// UFSHCI 2.0 Spec Section 5.5.4 Offset 7Ch: UTMRLCLR - UTP Task Management Request List CLear Register
+//
+typedef struct {
+ UINT32 UtmrlClr : 8; // UTP Task Management List Clear Register
+ UINT32 Rsvd1 : 24;
+} UFS_HC_UTMRLCLR;
+
+#if 0
+//
+// UFSHCI 2.0 Spec Section 5.5.5 Offset 80h: UTMRLRSR - UTP Task Management Request List Run Stop Register
+//
+typedef struct {
+ UINT32 UtmrlRsr : 1; // UTP Task Management Request List Run-Stop Register
+ UINT32 Rsvd1 : 31;
+} UFS_HC_UTMRLRSR;
+#endif
+
+//
+// UFSHCI 2.0 Spec Section 5.6.1 Offset 90h: UICCMD - UIC Command
+//
+typedef struct {
+ UINT32 CmdOp : 8; // Command Opcode
+ UINT32 Rsvd1 : 24;
+} UFS_HC_UICCMD;
+
+//
+// UFSHCI 2.0 Spec Section 5.6.2 Offset 94h: UICCMDARG1 - UIC Command Argument 1
+//
+#define UFS_HC_UICCMD_ARG1 UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.6.2 Offset 98h: UICCMDARG2 - UIC Command Argument 2
+//
+#define UFS_HC_UICCMD_ARG2 UINT32
+
+//
+// UFSHCI 2.0 Spec Section 5.6.2 Offset 9ch: UICCMDARG3 - UIC Command Argument 3
+//
+#define UFS_HC_UICCMD_ARG3 UINT32
+
+//
+// UIC command opcodes
+//
+typedef enum {
+ UfsUicDmeGet = 0x01,
+ UfsUicDmeSet = 0x02,
+ UfsUicDmePeerGet = 0x03,
+ UfsUicDmePeerSet = 0x04,
+ UfsUicDmePwrOn = 0x10,
+ UfsUicDmePwrOff = 0x11,
+ UfsUicDmeEnable = 0x12,
+ UfsUicDmeReset = 0x14,
+ UfsUicDmeEndpointReset = 0x15,
+ UfsUicDmeLinkStartup = 0x16,
+ UfsUicDmeHibernateEnter = 0x17,
+ UfsUicDmeHibernateExit = 0x18,
+ UfsUicDmeTestMode = 0x1A
+} UFS_UIC_OPCODE;
+
+//
+// UFSHCI 2.0 Spec Section 6.1.1 - UTP Transfer Request Descriptor
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT32 Rsvd1 : 24;
+ UINT32 Int : 1; /* Interrupt */
+ UINT32 Dd : 2; /* Data Direction */
+ UINT32 Rsvd2 : 1;
+ UINT32 Ct : 4; /* Command Type */
+
+ //
+ // DW1
+ //
+ UINT32 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT32 Ocs : 8; /* Overall Command Status */
+ UINT32 Rsvd4 : 24;
+
+ //
+ // DW3
+ //
+ UINT32 Rsvd5;
+
+ //
+ // DW4
+ //
+ UINT32 Rsvd6 : 7;
+ UINT32 UcdBa : 25; /* UTP Command Descriptor Base Address */
+
+ //
+ // DW5
+ //
+ UINT32 UcdBaU; /* UTP Command Descriptor Base Address Upper 32-bits */
+
+ //
+ // DW6
+ //
+ UINT16 RuL; /* Response UPIU Length */
+ UINT16 RuO; /* Response UPIU Offset */
+
+ //
+ // DW7
+ //
+ UINT16 PrdtL; /* PRDT Length */
+ UINT16 PrdtO; /* PRDT Offset */
+} UTP_TRD;
+
+typedef enum {
+ UfsNoData = 0,
+ UfsDataOut = 1,
+ UfsDataIn = 2,
+ UfsDdReserved
+} UFS_DATA_DIRECTION;
+
+typedef struct {
+ //
+ // DW0
+ //
+ UINT32 Rsvd1 : 2;
+ UINT32 DbAddr : 30; /* Data Base Address */
+
+ //
+ // DW1
+ //
+ UINT32 DbAddrU; /* Data Base Address Upper 32-bits */
+
+ //
+ // DW2
+ //
+ UINT32 Rsvd2;
+
+ //
+ // DW3
+ //
+ UINT32 DbCount : 18; /* Data Byte Count */
+ UINT32 Rsvd3 : 14;
+} UTP_TR_PRD;
+
+//
+// UFSHCI 2.0 Spec Section 6.2.1 - UTP Task Management Request Descriptor
+//
+typedef struct {
+ //
+ // DW0
+ //
+ UINT32 Rsvd1 : 24;
+ UINT32 Int : 1; /* Interrupt */
+ UINT32 Rsvd2 : 7;
+
+ //
+ // DW1
+ //
+ UINT32 Rsvd3;
+
+ //
+ // DW2
+ //
+ UINT32 Ocs : 8; /* Overall Command Status */
+ UINT32 Rsvd4 : 24;
+
+ //
+ // DW3
+ //
+ UINT32 Rsvd5;
+
+ //
+ // DW4 - DW11
+ //
+ UTP_TM_REQ_UPIU TmReq; /* Task Management Request UPIU */
+
+ //
+ // DW12 - DW19
+ //
+ UTP_TM_RESP_UPIU TmResp; /* Task Management Response UPIU */
+} UTP_TMRD;
+
+#pragma pack()
+
+#endif
diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h
index 99260652f4c0..1287fca30c67 100644
--- a/MdePkg/Include/Library/ArmLib.h
+++ b/MdePkg/Include/Library/ArmLib.h
@@ -156,7 +156,7 @@ ArmInstructionCacheLineLength (
VOID
);
-UINTN
+UINT32
EFIAPI
ArmCacheWritebackGranule (
VOID
diff --git a/MdePkg/Include/Library/StackCheckLib.h b/MdePkg/Include/Library/StackCheckLib.h
new file mode 100644
index 000000000000..bfbaa20cadf3
--- /dev/null
+++ b/MdePkg/Include/Library/StackCheckLib.h
@@ -0,0 +1,78 @@
+/** @file
+ This library provides stack cookie checking functions for symbols inserted by the compiler. This header
+ is not intended to be used directly by modules, but rather defines the expected interfaces to each supported
+ compiler, so that if the compiler interface is updated it is easier to track.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef STACK_CHECK_LIB_H_
+#define STACK_CHECK_LIB_H_
+
+#include <Base.h>
+
+#if defined (__GNUC__) || defined (__clang__)
+
+// The __stack_chk_guard is a random value placed on the stack between the stack variables
+// and the return address so that continuously writing past the stack variables will cause
+// the stack cookie to be overwritten. Before the function returns, the stack cookie value
+// will be checked and if there is a mismatch then StackCheckLib handles the failure.
+extern VOID *__stack_chk_guard;
+
+/**
+ Called when a stack cookie check fails. The return address is the failing address.
+
+**/
+VOID
+EFIAPI
+__stack_chk_fail (
+ VOID
+ );
+
+#elif defined (_MSC_VER)
+
+// The __security_cookie is a random value placed on the stack between the stack variables
+// and the return address so that continuously writing past the stack variables will cause
+// the stack cookie to be overwritten. Before the function returns, the stack cookie value
+// will be checked and if there is a mismatch then StackCheckLib handles the failure.
+extern VOID *__security_cookie;
+
+/**
+ Called when a buffer check fails. This functionality is dependent on MSVC
+ C runtime libraries and so is unsupported in UEFI.
+
+**/
+VOID
+EFIAPI
+__report_rangecheckfailure (
+ VOID
+ );
+
+/**
+ The GS handler is for checking the stack cookie during SEH or
+ EH exceptions and is unsupported in UEFI.
+
+**/
+VOID
+EFIAPI
+__GSHandlerCheck (
+ VOID
+ );
+
+/**
+ Checks the stack cookie value against __security_cookie and calls the
+ stack cookie failure handler if there is a mismatch.
+
+ @param UINTN CheckValue The value to check against __security_cookie
+
+**/
+VOID
+EFIAPI
+__security_check_cookie (
+ UINTN CheckValue
+ );
+
+#endif // Compiler type
+
+#endif // STACK_CHECK_LIB_H_
diff --git a/MdePkg/Include/Library/StandaloneMmCoreEntryPoint.h b/MdePkg/Include/Library/StandaloneMmCoreEntryPoint.h
new file mode 100644
index 000000000000..1bc95d9508fb
--- /dev/null
+++ b/MdePkg/Include/Library/StandaloneMmCoreEntryPoint.h
@@ -0,0 +1,91 @@
+/** @file
+ Module entry point library for STANDALONE MM core.
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __MODULE_ENTRY_POINT_H__
+#define __MODULE_ENTRY_POINT_H__
+
+///
+/// Global variable that contains a pointer to the Hob List passed into the STANDALONE MM Core entry point.
+///
+extern VOID *gHobList;
+
+/**
+ The entry point of PE/COFF Image for the STANDALONE MM Core.
+
+ This function is the entry point for the STANDALONE MM Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the STANDALONE MM Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_ModuleEntryPoint (
+ IN VOID *HobStart
+ );
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ );
+
+/**
+ Auto generated function that calls the library constructors for all of the module's dependent libraries.
+
+ This function must be called by _ModuleEntryPoint().
+ This function calls the set of library constructors for the set of library instances
+ that a module depends on. This includes library instances that a module depends on
+ directly and library instances that a module depends on indirectly through other
+ libraries. This function is auto generated by build tools and those build tools are
+ responsible for collecting the set of library instances, determine which ones have
+ constructors, and calling the library constructors in the proper order based upon
+ each of the library instances own dependencies.
+
+ @param ImageHandle The image handle of the STANDALONE MM Core.
+ @param SystemTable A pointer to the EFI System Table.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ );
+
+/**
+ Autogenerated function that calls a set of module entry points.
+
+ This function must be called by _ModuleEntryPoint().
+ This function calls the set of module entry points.
+ This function is auto generated by build tools and those build tools are responsible
+ for collecting the module entry points and calling them in a specified order.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+ProcessModuleEntryPointList (
+ IN VOID *HobStart
+ );
+
+#endif
diff --git a/MdePkg/Include/Library/UefiUsbLib.h b/MdePkg/Include/Library/UefiUsbLib.h
index c570d71ad64a..a6570b7e8a9e 100644
--- a/MdePkg/Include/Library/UefiUsbLib.h
+++ b/MdePkg/Include/Library/UefiUsbLib.h
@@ -3,6 +3,7 @@
and the standard requests defined in USB 1.1 spec.
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2024, American Megatrends Intenational LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -552,4 +553,134 @@ UsbClearEndpointHalt (
OUT UINT32 *Status
);
+/**
+ Retrieve the interface descriptor details from the interface setting.
+
+ This is an extended version of UsbIo->GetInterfaceDescriptor. It returns the interface
+ descriptor for an alternate setting of the interface without executing SET_INTERFACE
+ transfer. It also returns the number of class specific interfaces.
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[out] Descriptor The caller allocated buffer to return the contents of the Interface descriptor.
+ @param[out] CsInterfaceNumber Number of class specific interfaces for this interface setting.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER Descriptor or CsInterfaceNumber is NULL.
+ @retval EFI_UNSUPPORTED Setting is greater than the number of alternate settings in this interface.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetInterfaceDescriptorSetting (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ OUT EFI_USB_INTERFACE_DESCRIPTOR *Descriptor,
+ OUT UINTN *CsInterfacesNumber
+ );
+
+/**
+ Retrieve the endpoint descriptor from the interface setting.
+
+ This is an extended version of UsbIo->GetEndpointDescriptor. It returns the endpoint
+ descriptor for an alternate setting of a given interface.
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ Note: The total number of endpoints can be retrieved from the interface descriptor
+ returned by EDKII_USBIO_EXT_GET_INTERFACE_DESCRIPTOR function.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Index of the endpoint to retrieve. The valid range is 0..15.
+ @param[out] Descriptor A pointer to the caller allocated USB Interface Descriptor.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER Descriptor is NULL.
+ @retval EFI_UNSUPPORTED Setting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of endpoints in this interface.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetEndpointDescriptorSetting (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ OUT EFI_USB_ENDPOINT_DESCRIPTOR *Descriptor
+ );
+
+/**
+ Retrieve class specific interface descriptor.
+
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Zero-based index of the class specific interface.
+ @param[in][out] BufferSize On input, the size in bytes of the return Descriptor buffer.
+ On output the size of data returned in Descriptor.
+ @param[out] Descriptor The buffer to return the contents of the class specific interface descriptor. May
+ be NULL with a zero BufferSize in order to determine the size buffer needed.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL.
+ Buffer is NULL and *BufferSize is not zero.
+ @retval EFI_UNSUPPORTED Setting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of class specific interfaces.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been updated with the size
+ needed to complete the request.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetCsInterfaceDescriptor (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Retrieve class specific endpoint descriptor.
+
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Zero-based index of the non-zero endpoint.
+ @param[in][out] BufferSize On input, the size in bytes of the return Descriptor buffer.
+ On output the size of data returned in Descriptor.
+ @param[out] Descriptor The buffer to return the contents of the class specific endpoint descriptor. May
+ be NULL with a zero BufferSize in order to determine the size buffer needed.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL.
+ Buffer is NULL and *BufferSize is not zero.
+ @retval EFI_UNSUPPORTED Setting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of endpoints in this interface.
+ Endpoint does not have class specific endpoint descriptor.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been updated with the size
+ needed to complete the request.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetCsEndpointDescriptor (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
#endif
diff --git a/MdePkg/Include/Pi/PiHob.h b/MdePkg/Include/Pi/PiHob.h
index d2a2da43c454..1040e6232540 100644
--- a/MdePkg/Include/Pi/PiHob.h
+++ b/MdePkg/Include/Pi/PiHob.h
@@ -5,7 +5,7 @@ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
- PI Version 1.6
+ PI Version 1.9
**/
@@ -291,6 +291,7 @@ typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
#define EFI_RESOURCE_ATTRIBUTE_ENCRYPTED 0x04000000
#define EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE 0x08000000
+#define EFI_RESOURCE_ATTRIBUTE_HOT_PLUGGABLE 0x10000000
//
// Physical memory relative reliability attribute. This
// memory provides higher reliability relative to other
diff --git a/MdePkg/Include/Pi/PiStatusCode.h b/MdePkg/Include/Pi/PiStatusCode.h
index 2daa8887ebae..dc0186d578d4 100644
--- a/MdePkg/Include/Pi/PiStatusCode.h
+++ b/MdePkg/Include/Pi/PiStatusCode.h
@@ -2,6 +2,7 @@
StatusCode related definitions in PI.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
@@ -140,6 +141,7 @@ typedef struct {
#define EFI_COMPUTING_UNIT_CACHE (EFI_COMPUTING_UNIT | 0x00040000)
#define EFI_COMPUTING_UNIT_MEMORY (EFI_COMPUTING_UNIT | 0x00050000)
#define EFI_COMPUTING_UNIT_CHIPSET (EFI_COMPUTING_UNIT | 0x00060000)
+#define EFI_COMPUTING_UNIT_MANAGEABILITY (EFI_COMPUTING_UNIT | 0x00070000)
///@}
///
@@ -344,6 +346,16 @@ typedef struct {
///@}
///
+/// Computing Unit Manageability Subclass Error Code definitions.
+/// The detail information is reported by REPORT_STATUS_CODE_WITH_EXTENDED_DATA
+// with ASCII string in EFI_STATUS_CODE_STRING_DATA.
+///@{
+#define EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_MANAGEABILITY_EC_REDFISH_HOST_INTERFACE_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_MANAGEABILITY_EC_REDFISH_BOOTSTRAP_CREDENTIAL_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+///
/// Peripheral Subclass definitions.
/// Values of 12-127 are reserved for future use by this specification.
/// Values of 128-255 are reserved for OEM use.
diff --git a/MdePkg/Include/Ppi/Rng.h b/MdePkg/Include/Ppi/Rng.h
new file mode 100644
index 000000000000..f44c5cc22122
--- /dev/null
+++ b/MdePkg/Include/Ppi/Rng.h
@@ -0,0 +1,27 @@
+/** @file
+ The Random Number Generator (RNG) PPI is used to provide random bits for use
+ in PEIMs, or entropy for seeding other random number generators. The PPI was
+ introduced in the PI 1.9 Specification.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef RNG_PPI_H_
+#define RNG_PPI_H_
+
+#include <Guid/Rng.h>
+
+///
+/// Global ID for the Random Number Generator PPI
+///
+#define RNG_PPI_GUID \
+ { \
+ 0xeaed0a7e, 0x1a70, 0x4c2b, { 0x85, 0x58, 0x37, 0x17, 0x74, 0x56, 0xd8, 0x06 } \
+ }
+
+typedef EFI_RNG_INTERFACE RNG_PPI;
+
+extern EFI_GUID gEfiRngPpiGuid;
+
+#endif
diff --git a/MdePkg/Include/Protocol/AtaPassThru.h b/MdePkg/Include/Protocol/AtaPassThru.h
index 545a88db7550..d6f0e79e251a 100644
--- a/MdePkg/Include/Protocol/AtaPassThru.h
+++ b/MdePkg/Include/Protocol/AtaPassThru.h
@@ -270,6 +270,10 @@ EFI_STATUS
If PortMultiplierPort is the port multiplier port number of the last ATA device on the port of
the ATA controller, then EFI_NOT_FOUND is returned.
+ When port multiplier is not connected to the Port, GetNextDevice() may either return
+ EFI_SUCCESS and set PortMultiplierPort to 0xFFFF or return EFI_NOT_FOUND (in which case the
+ PortMultiplierPort value is undefined).
+
@param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
@param[in] Port The port number present on the ATA controller.
@param[in,out] PortMultiplierPort On input, a pointer to the port multiplier port number of an
diff --git a/MdePkg/Include/Protocol/BootManagerPolicy.h b/MdePkg/Include/Protocol/BootManagerPolicy.h
index dc27ccaa1dfd..ed4d86b9b871 100644
--- a/MdePkg/Include/Protocol/BootManagerPolicy.h
+++ b/MdePkg/Include/Protocol/BootManagerPolicy.h
@@ -5,6 +5,7 @@
to connect devices using platform policy.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -31,6 +32,11 @@
0x113B2126, 0xFC8A, 0x11E3, { 0xBD, 0x6C, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } \
}
+#define EFI_BOOT_MANAGER_POLICY_STORAGE_GUID \
+ { \
+ 0xCD68FE79, 0xD3CB, 0x436E, { 0xA8, 0x50, 0xF4, 0x43, 0xC8, 0x8C, 0xFB, 0x49 } \
+ }
+
typedef struct _EFI_BOOT_MANAGER_POLICY_PROTOCOL EFI_BOOT_MANAGER_POLICY_PROTOCOL;
#define EFI_BOOT_MANAGER_POLICY_PROTOCOL_REVISION 0x00010000
@@ -98,6 +104,12 @@ EFI_STATUS
EFI_BOOT_SERVICES.ConnectController(). If the Boot Manager has policy
associated with connect all UEFI drivers this policy will be used.
+ If Class is EFI_BOOT_MANAGER_POLICY_STORAGE_GUID then the Boot Manager will
+ connect the protocols associated with the discoverable storage disks. This may include
+ EFI_BLOCK_IO_PROTOCOL, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, or other storage protocols
+ appropriate to the device. Some platforms may choose to restrict the connected
+ devices to exclude USB or other peripherals.
+
A platform can also define platform specific Class values as a properly generated
EFI_GUID would never conflict with this specification.
@@ -128,5 +140,6 @@ extern EFI_GUID gEfiBootManagerPolicyProtocolGuid;
extern EFI_GUID gEfiBootManagerPolicyConsoleGuid;
extern EFI_GUID gEfiBootManagerPolicyNetworkGuid;
extern EFI_GUID gEfiBootManagerPolicyConnectAllGuid;
+extern EFI_GUID gEfiBootManagerPolicyStorageGuid;
#endif
diff --git a/MdePkg/Include/Protocol/CcMeasurement.h b/MdePkg/Include/Protocol/CcMeasurement.h
index 43d24036c5b8..ef9e111605d5 100644
--- a/MdePkg/Include/Protocol/CcMeasurement.h
+++ b/MdePkg/Include/Protocol/CcMeasurement.h
@@ -33,9 +33,10 @@ typedef struct {
//
// EFI_CC Type/SubType definition
//
-#define EFI_CC_TYPE_NONE 0
-#define EFI_CC_TYPE_SEV 1
-#define EFI_CC_TYPE_TDX 2
+#define EFI_CC_TYPE_NONE 0
+#define EFI_CC_TYPE_SEV 1
+#define EFI_CC_TYPE_TDX 2
+#define EFI_CC_TYPE_APTEE 3
typedef struct {
UINT8 Type;
diff --git a/MdePkg/Include/Protocol/DebugSupport.h b/MdePkg/Include/Protocol/DebugSupport.h
index 8882d4425819..65f737140e7d 100644
--- a/MdePkg/Include/Protocol/DebugSupport.h
+++ b/MdePkg/Include/Protocol/DebugSupport.h
@@ -680,23 +680,23 @@ typedef struct {
UINT32 STVAL;
} EFI_SYSTEM_CONTEXT_RISCV64;
-//
-// LoongArch processor exception types.
-//
-// The exception types is located in the CSR ESTAT
-// register offset 16 bits, width 6 bits.
-//
-// If you want to register an exception hook, you can
-// shfit the number left by 16 bits, and the exception
-// handler will know the types.
-//
-// For example:
-// mCpu->CpuRegisterInterruptHandler (
-// mCpu,
-// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT),
-// PpiExceptionHandler
-// );
-//
+///
+/// LoongArch processor exception types.
+///
+/// The exception types is located in the CSR ESTAT
+/// register offset 16 bits, width 6 bits.
+///
+/// If you want to register an exception hook, you can
+/// shfit the number left by 16 bits, and the exception
+/// handler will know the types.
+///
+/// For example:
+/// mCpu->CpuRegisterInterruptHandler (
+/// mCpu,
+/// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT),
+/// PpiExceptionHandler
+/// );
+///
#define EXCEPT_LOONGARCH_INT 0
#define EXCEPT_LOONGARCH_PIL 1
#define EXCEPT_LOONGARCH_PIS 2
@@ -716,11 +716,22 @@ typedef struct {
#define EXCEPT_LOONGARCH_SXD 16
#define EXCEPT_LOONGARCH_ASXD 17
#define EXCEPT_LOONGARCH_FPE 18
-#define EXCEPT_LOONGARCH_TBR 64 // For code only, there is no such type in the ISA spec, the TLB refill is defined for an independent exception.
+#define EXCEPT_LOONGARCH_WPE 19
+#define EXCEPT_LOONGARCH_BTD 20
+#define EXCEPT_LOONGARCH_BTE 21
+#define EXCEPT_LOONGARCH_GSPR 22
+#define EXCEPT_LOONGARCH_HVC 23
+#define EXCEPT_LOONGARCH_GCXC 24
-//
-// LoongArch processor Interrupt types.
-//
+///
+/// For coding convenience, define the maximum valid
+/// LoongArch exception.
+///
+#define MAX_LOONGARCH_EXCEPTION 64
+
+///
+/// LoongArch processor Interrupt types.
+///
#define EXCEPT_LOONGARCH_INT_SIP0 0
#define EXCEPT_LOONGARCH_INT_SIP1 1
#define EXCEPT_LOONGARCH_INT_IP0 2
@@ -735,11 +746,11 @@ typedef struct {
#define EXCEPT_LOONGARCH_INT_TIMER 11
#define EXCEPT_LOONGARCH_INT_IPI 12
-//
-// For coding convenience, define the maximum valid
-// LoongArch interrupt.
-//
-#define MAX_LOONGARCH_INTERRUPT 14
+///
+/// For coding convenience, define the maximum valid
+/// LoongArch interrupt.
+///
+#define MAX_LOONGARCH_INTERRUPT 16
typedef struct {
UINT64 R0;
diff --git a/MdePkg/Include/Protocol/FirmwareManagement.h b/MdePkg/Include/Protocol/FirmwareManagement.h
index 458101584396..e0dbee1c17da 100644
--- a/MdePkg/Include/Protocol/FirmwareManagement.h
+++ b/MdePkg/Include/Protocol/FirmwareManagement.h
@@ -351,7 +351,10 @@ EFI_STATUS
@retval EFI_INVALID_PARAMETER The Image was NULL.
@retval EFI_NOT_FOUND The current image is not copied to the buffer.
@retval EFI_UNSUPPORTED The operation is not supported.
- @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+ @retval EFI_SECURITY_VIOLATION The operation could not be completed due to an image corruption.
+ If the image is able to be read, the Image buffer will be updated
+ with the retrieved image contents.
+ @retval EFI_DEVICE_ERROR The image could not be read.
**/
typedef
diff --git a/MdePkg/Include/Protocol/PxeBaseCode.h b/MdePkg/Include/Protocol/PxeBaseCode.h
index 4fc44ca31300..e01f6fed71e7 100644
--- a/MdePkg/Include/Protocol/PxeBaseCode.h
+++ b/MdePkg/Include/Protocol/PxeBaseCode.h
@@ -34,7 +34,7 @@ typedef EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE;
///
/// Default IP TTL and ToS.
///
-#define DEFAULT_TTL 16
+#define DEFAULT_TTL 64
#define DEFAULT_ToS 0
///
diff --git a/MdePkg/Include/Protocol/Rng.h b/MdePkg/Include/Protocol/Rng.h
index 882d66011867..5c3e1daa1e2e 100644
--- a/MdePkg/Include/Protocol/Rng.h
+++ b/MdePkg/Include/Protocol/Rng.h
@@ -8,8 +8,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#ifndef __EFI_RNG_PROTOCOL_H__
-#define __EFI_RNG_PROTOCOL_H__
+#ifndef EFI_RNG_PROTOCOL_H_
+#define EFI_RNG_PROTOCOL_H_
+
+#include <Guid/Rng.h>
///
/// Global ID for the Random Number Generator Protocol
@@ -19,142 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
}
-typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
-
-///
-/// A selection of EFI_RNG_PROTOCOL algorithms.
-/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
-/// vendors or other industry standards.
-///
-
-typedef EFI_GUID EFI_RNG_ALGORITHM;
-
-///
-/// The algorithms corresponds to SP800-90 as defined in
-/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
-/// Bit Generators", March 2007.
-///
-#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
- { \
- 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
- }
-#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
- { \
- 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
- }
-#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
- { \
- 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
- }
-///
-/// The algorithms correspond to X9.31 as defined in
-/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
-/// the 3-Key Triple DES and AES Algorithm", January 2005.
-///
-#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
- { \
- 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
- }
-#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
- { \
- 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
- }
-///
-/// The "raw" algorithm, when supported, is intended to provide entropy directly from
-/// the source, without it going through some deterministic random bit generator.
-///
-#define EFI_RNG_ALGORITHM_RAW \
- { \
- 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
- }
-///
-/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant
-/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be
-/// inclusive of different geographies.
-///
-#define EFI_RNG_ALGORITHM_ARM_RNDR \
- { \
- 0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \
- }
-
-/**
- Returns information about the random number generation implementation.
-
- @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
- @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
- On output with a return code of EFI_SUCCESS, the size
- in bytes of the data returned in RNGAlgorithmList. On output
- with a return code of EFI_BUFFER_TOO_SMALL,
- the size of RNGAlgorithmList required to obtain the list.
- @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
- with one EFI_RNG_ALGORITHM element for each supported
- RNG algorithm. The list must not change across multiple
- calls to the same driver. The first algorithm in the list
- is the default algorithm for the driver.
-
- @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
- @retval EFI_UNSUPPORTED The services is not supported by this driver.
- @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
- hardware or firmware error.
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
- @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_RNG_GET_INFO)(
- IN EFI_RNG_PROTOCOL *This,
- IN OUT UINTN *RNGAlgorithmListSize,
- OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
- );
-
-/**
- Produces and returns an RNG value using either the default or specified RNG algorithm.
-
- @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
- @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
- algorithm to use. May be NULL in which case the function will
- use its default RNG algorithm.
- @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
- RNGValue. The driver shall return exactly this numbers of bytes.
- @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
- resulting RNG value.
-
- @retval EFI_SUCCESS The RNG value was returned successfully.
- @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
- this driver.
- @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
- firmware error.
- @retval EFI_NOT_READY There is not enough random data available to satisfy the length
- requested by RNGValueLength.
- @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_RNG_GET_RNG)(
- IN EFI_RNG_PROTOCOL *This,
- IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL,
- IN UINTN RNGValueLength,
- OUT UINT8 *RNGValue
- );
-
-///
-/// The Random Number Generator (RNG) protocol provides random bits for use in
-/// applications, or entropy for seeding other random number generators.
-///
-struct _EFI_RNG_PROTOCOL {
- EFI_RNG_GET_INFO GetInfo;
- EFI_RNG_GET_RNG GetRNG;
-};
+typedef EFI_RNG_INTERFACE EFI_RNG_PROTOCOL;
extern EFI_GUID gEfiRngProtocolGuid;
-extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
-extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
-extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
-extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
-extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
-extern EFI_GUID gEfiRngAlgorithmRaw;
-extern EFI_GUID gEfiRngAlgorithmArmRndr;
#endif
diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h
index 7c21234eecb2..d469d2a36ce0 100644
--- a/MdePkg/Include/Uefi/UefiSpec.h
+++ b/MdePkg/Include/Uefi/UefiSpec.h
@@ -106,6 +106,16 @@ typedef enum {
#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000ULL
//
+// If this flag is set, the memory region is present and capable of having
+// memory dynamically removed from the platform. This attribute serves as
+// a hint to the OS prior to its ACPI subsystem initialization to avoid
+// allocating this memory for core OS data or code that cannot be dynamically
+// relocated at runtime. If this flag is clear, the memory region is not
+// capable of being dynamically removed from the platform at runtime.
+//
+#define EFI_MEMORY_HOT_PLUGGABLE 0x0000000000100000
+
+//
// Runtime memory attribute
//
#define EFI_MEMORY_RUNTIME 0x8000000000000000ULL
@@ -1839,21 +1849,24 @@ EFI_STATUS
//
// EFI Runtime Services Table
//
-#define EFI_SYSTEM_TABLE_SIGNATURE SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
-#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
-#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
-#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
-#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
-#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
-#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
-#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
-#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
-#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
-#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
-#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
-#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
-#define EFI_SYSTEM_TABLE_REVISION EFI_2_70_SYSTEM_TABLE_REVISION
-#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_SIGNATURE SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
+#define EFI_2_110_SYSTEM_TABLE_REVISION ((2 << 16) | (110))
+#define EFI_2_100_SYSTEM_TABLE_REVISION ((2 << 16) | (100))
+#define EFI_2_90_SYSTEM_TABLE_REVISION ((2 << 16) | (90))
+#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
+#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
+#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
+#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
+#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
+#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
+#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
+#define EFI_SYSTEM_TABLE_REVISION EFI_2_70_SYSTEM_TABLE_REVISION
+#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
#define EFI_RUNTIME_SERVICES_SIGNATURE SIGNATURE_64 ('R','U','N','T','S','E','R','V')
#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION
diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
index ebe1eb6b26c8..03532c8c4d96 100644
--- a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
+++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
@@ -14,17 +14,21 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
-typedef UINT8 uint8_t;
-typedef UINT16 uint16_t;
-typedef INT32 int32_t;
-typedef UINT32 uint32_t;
-typedef UINT64 uint64_t;
-typedef UINTN uintptr_t;
-typedef UINTN size_t;
-typedef BOOLEAN bool;
-
+typedef UINT8 uint8_t;
+typedef UINT16 uint16_t;
+typedef INT32 int32_t;
+typedef UINT32 uint32_t;
+typedef UINT64 uint64_t;
+typedef UINTN uintptr_t;
+typedef UINTN size_t;
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+/* bool, true and false are keywords. */
+#else
+typedef BOOLEAN bool;
#define true (1 == 1)
#define false (1 == 0)
+#endif
//
// Definitions for global constants used by libfdt library routines
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index 9e74622fe48a..8c9f0c9450e4 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -24,6 +24,7 @@
**/
#include "BasePeCoffLibInternals.h"
+#include <Library/SafeIntLib.h>
/**
Adjust some fields in section header for TE image.
@@ -975,6 +976,7 @@ PeCoffLoaderRelocateImage (
PHYSICAL_ADDRESS BaseAddress;
UINT32 NumberOfRvaAndSizes;
UINT32 TeStrippedOffset;
+ UINT32 EndAddress;
ASSERT (ImageContext != NULL);
@@ -1054,22 +1056,24 @@ PeCoffLoaderRelocateImage (
RelocDir = &Hdr.Te->DataDirectory[0];
}
- if ((RelocDir != NULL) && (RelocDir->Size > 0) && ((RelocDir->Size - 1) < (MAX_UINT32 - RelocDir->VirtualAddress))) {
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
- RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
- ImageContext,
- RelocDir->VirtualAddress + RelocDir->Size - 1,
- TeStrippedOffset
- );
+ RelocBase = NULL;
+ RelocBaseEnd = NULL;
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
+ Status = SafeUint32Add (RelocDir->VirtualAddress, (RelocDir->Size - 1), &EndAddress);
+ if (!RETURN_ERROR (Status)) {
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
+ ImageContext,
+ EndAddress,
+ TeStrippedOffset
+ );
+ }
+
if ((RelocBase == NULL) || (RelocBaseEnd == NULL) || ((UINTN)RelocBaseEnd < (UINTN)RelocBase)) {
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ DEBUG ((DEBUG_ERROR, "Relocation block is not valid\n"));
return RETURN_LOAD_ERROR;
}
- } else {
- //
- // Set base and end to bypass processing below.
- //
- RelocBase = RelocBaseEnd = NULL;
}
RelocBaseOrg = RelocBase;
@@ -1767,6 +1771,7 @@ PeCoffLoaderRelocateImageForRuntime (
UINTN Adjust;
RETURN_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINT32 EndAddress;
if ((RelocationData == NULL) || (ImageBase == 0x0) || (VirtImageBase == 0x0)) {
return;
@@ -1828,12 +1833,15 @@ PeCoffLoaderRelocateImageForRuntime (
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;
if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (&ImageContext, RelocDir->VirtualAddress, 0);
- RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
- &ImageContext,
- RelocDir->VirtualAddress + RelocDir->Size - 1,
- 0
- );
+ Status = SafeUint32Add (RelocDir->VirtualAddress, (RelocDir->Size - 1), &EndAddress);
+ if (!RETURN_ERROR (Status)) {
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (&ImageContext, RelocDir->VirtualAddress, 0);
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
+ &ImageContext,
+ EndAddress,
+ 0
+ );
+ }
}
if ((RelocBase == NULL) || (RelocBaseEnd == NULL) || ((UINTN)RelocBaseEnd < (UINTN)RelocBase)) {
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
index 0172d2691c68..80fd5344539d 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
@@ -58,4 +58,5 @@
DebugLib
PeCoffExtraActionLib
BaseMemoryLib
+ SafeIntLib
diff --git a/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c
index 738b056dd1f5..f3ec94c07c5d 100644
--- a/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c
+++ b/MdePkg/Library/BasePeCoffLib/LoongArch/PeCoffLoaderEx.c
@@ -104,7 +104,15 @@ PeCoffLoaderImageFormatSupported (
IN UINT16 Machine
)
{
- if (Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {
+ /*
+ * ARM64 and X64 may allow such foreign images to be used when
+ * a driver implementing EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL is
+ * present.
+ */
+ if ((Machine == IMAGE_FILE_MACHINE_LOONGARCH64) ||
+ (Machine == IMAGE_FILE_MACHINE_ARM64) ||
+ (Machine == IMAGE_FILE_MACHINE_X64))
+ {
return TRUE;
}
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
index 688abba68b9e..10de2ecca456 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include "BaseRngLibInternals.h"
+#include "ArmRng.h"
.text
.p2align 2
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
index 76f6e960ac11..c8666926c4db 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
@@ -8,7 +8,7 @@
;
;------------------------------------------------------------------------------
-#include "BaseRngLibInternals.h"
+#include "ArmRng.h"
EXPORT ArmRndr
AREA BaseLib_LowLevel, CODE, READONLY
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
index 5937dd7deac2..12521a1a6f83 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
@@ -11,6 +11,8 @@
#ifndef ARM_RNG_H_
#define ARM_RNG_H_
+#include <AArch64/AArch64.h>
+
/**
Generates a random number using RNDR.
Returns TRUE on success; FALSE on failure.
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
index 221f158066a7..3b5bdcf8a2e3 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
+++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
@@ -69,11 +69,4 @@ ArchIsRngSupported (
VOID
);
-#if defined (MDE_CPU_AARCH64)
-
-// RNDR, Random Number
-#define RNDR S3_3_C2_C4_0
-
-#endif
-
#endif // BASE_RNGLIB_INTERNALS_H_
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
index 63ad43283d8d..d37808913875 100644
--- a/MdePkg/Library/BaseRngLib/Rand/RdRand.c
+++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
@@ -2,6 +2,7 @@
Random number generator services that uses RdRand instruction access
to provide high-quality random numbers.
+Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
Copyright (c) 2023, Arm Limited. All rights reserved.<BR>
Copyright (c) 2022, Pedro Falcato. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
@@ -23,8 +24,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
#define RDRAND_MASK BIT30
-STATIC BOOLEAN mRdRandSupported;
-
//
// Intel SDM says 10 tries is good enough for reliable RDRAND usage.
//
@@ -124,20 +123,6 @@ BaseRngLibConstructor (
VOID
)
{
- UINT32 RegEcx;
-
- //
- // Determine RDRAND support by examining bit 30 of the ECX register returned by
- // CPUID. A value of 1 indicates that processor support RDRAND instruction.
- //
- AsmCpuid (1, 0, 0, &RegEcx, 0);
-
- mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
-
- if (mRdRandSupported) {
- mRdRandSupported = TestRdRand ();
- }
-
return EFI_SUCCESS;
}
@@ -156,7 +141,6 @@ ArchGetRandomNumber16 (
OUT UINT16 *Rand
)
{
- ASSERT (mRdRandSupported);
return AsmRdRand16 (Rand);
}
@@ -175,7 +159,6 @@ ArchGetRandomNumber32 (
OUT UINT32 *Rand
)
{
- ASSERT (mRdRandSupported);
return AsmRdRand32 (Rand);
}
@@ -194,7 +177,6 @@ ArchGetRandomNumber64 (
OUT UINT64 *Rand
)
{
- ASSERT (mRdRandSupported);
return AsmRdRand64 (Rand);
}
@@ -211,7 +193,22 @@ ArchIsRngSupported (
VOID
)
{
- return mRdRandSupported;
+ BOOLEAN RdRandSupported;
+ UINT32 RegEcx;
+
+ //
+ // Determine RDRAND support by examining bit 30 of the ECX register returned by
+ // CPUID. A value of 1 indicates that processor support RDRAND instruction.
+ //
+ AsmCpuid (1, 0, 0, &RegEcx, 0);
+
+ RdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+ if (RdRandSupported) {
+ RdRandSupported = TestRdRand ();
+ }
+
+ return RdRandSupported;
}
/**
diff --git a/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf b/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
index 279263b04119..10b57e236d85 100644
--- a/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+++ b/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
@@ -33,4 +33,5 @@
[LibraryClasses]
BaseLib
DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.c b/MdePkg/Library/DxeRngLib/DxeRngLib.c
index 2afce29d589f..c7c146e10c94 100644
--- a/MdePkg/Library/DxeRngLib/DxeRngLib.c
+++ b/MdePkg/Library/DxeRngLib/DxeRngLib.c
@@ -32,7 +32,7 @@ typedef struct {
// These represent UEFI SPEC defined algorithms that should be supported by
// the RNG protocol and are generally considered secure.
//
-static GLOBAL_REMOVE_IF_UNREFERENCED SECURE_RNG_ALGO_ARRAY mSecureHashAlgorithms[] = {
+static SECURE_RNG_ALGO_ARRAY mSecureHashAlgorithms[] = {
#ifdef MDE_CPU_AARCH64
{
&gEfiRngAlgorithmArmRndr, // unspecified SP800-90A DRBG (through RNDR instr.)
@@ -204,7 +204,10 @@ GenerateRandomNumberViaNist800Algorithm (
}
}
- if (!PcdGetBool (PcdEnforceSecureRngAlgorithms)) {
+ if (PcdGetBool (PcdEnforceSecureRngAlgorithms)) {
+ // Platform does not permit the use of the default (insecure) algorithm.
+ Status = EFI_SECURITY_VIOLATION;
+ } else {
// If all the other methods have failed, use the default method from the RngProtocol
Status = mRngProtocol->GetRNG (mRngProtocol, NULL, BufferSize, Buffer);
DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status));
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
new file mode 100644
index 000000000000..f508f692d3f9
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
@@ -0,0 +1,56 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Module Name:
+#
+# DynamicCookie.S
+#
+# Abstract:
+#
+# Generates random number through the RNDR instruction on a 64-bit AARCH64 platform
+# to store a random value in the GCC __stack_check_guard stack cookie.
+# The first byte is 0'd to prevent string copy functions from clobbering
+# the stack cookie.
+#
+# Notes:
+#
+# If RNDR fails, the build time static stack cookie value will be used instead.
+#
+#------------------------------------------------------------------------------
+
+#include <AArch64/AArch64.h>
+
+.text
+.p2align 2
+
+GCC_ASM_IMPORT(__stack_chk_guard)
+GCC_ASM_IMPORT(_CModuleEntryPoint)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# _ModuleEntryPoint (
+# Parameters are passed through.
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(_ModuleEntryPoint):
+ AARCH64_BTI(c)
+
+ mrs x9, ID_AA64ISAR0_EL1 // Read the AArch64 Instruction Set Attribute Register 0
+ ubfx x9, x9, #60, #4 // Extract the RNDR bit field (bits 60-63)
+ cbz x9, c_entry // If RNDR is not supported, jump to c_entry
+
+ mrs x9, RNDR // Generate a random number
+ b.eq c_entry // RNDR sets NZCV to 0b0100 on failure
+ // So if the zero flag is set, use the static stack guard
+
+ and x9, x9, #0xFFFFFFFFFFFFFF00 // Zero the first byte of the random value
+
+ adrp x8, ASM_PFX(__stack_chk_guard) // Load the page address of __stack_chk_guard
+ str x9, [x8, :lo12:ASM_PFX(__stack_chk_guard)] // Store the random value in __stack_chk_guard
+
+c_entry:
+ b ASM_PFX(_CModuleEntryPoint) // Jump to the C module entry point
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
new file mode 100644
index 000000000000..5118132bd2c3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
@@ -0,0 +1,70 @@
+/** @file
+ Entry point to the DXE Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/DxeCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the DXE Core.
+
+ This function is the entry point for the DXE Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The DXE Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the DXE Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the DXE Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+
+ //
+ // Should never return
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
new file mode 100644
index 000000000000..e6515659a9e0
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for DXE core.
+//
+// Module entry point library for DXE core.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for DXE core"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for DXE core."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
new file mode 100644
index 000000000000..1da877ae1d97
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for DXE core that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeCoreEntryPointDynamicInit
+ MODULE_UNI_FILE = DxeCore/DxeCoreEntryPoint.uni
+ FILE_GUID = FD044D85-1407-4043-B527-471F16ABD8C6
+ MODULE_TYPE = DXE_CORE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeCoreEntryPoint|DXE_CORE
+
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ DxeCore/DxeCoreEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
new file mode 100644
index 000000000000..c3c3e0e9931c
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __stack_chk_guard is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__stack_chk_guard)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
new file mode 100644
index 000000000000..2b8ec94fdbe9
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __security_cookie is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __security_cookie, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__security_cookie)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __security_cookie value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __security_cookie
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
new file mode 100644
index 000000000000..204702727319
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
@@ -0,0 +1,65 @@
+/** @file
+ Entry point to the Standalone Mm Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/StandaloneMmCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the STANDALONE MM Core.
+
+ This function is the entry point for the STANDALONE MM Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the STANDALONE MM Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the Standalone MM Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
new file mode 100644
index 000000000000..b82415e6b8fc
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
@@ -0,0 +1,38 @@
+## @file
+# Module entry point library for StandaloneMm core that dynamically updates the stack cookie.
+# The AARCH64 version of this library lives in ArmPkg.
+#
+# Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPointDynamicInit
+ FILE_GUID = 490073A1-4DBC-4E9E-B30D-A4204139FC5F
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources.X64]
+ StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
new file mode 100644
index 000000000000..51df419953d5
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
@@ -0,0 +1,135 @@
+/** @file
+ Entry point to a Standalone MM driver.
+
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Protocol/LoadedImage.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Library/StandaloneMmDriverEntryPoint.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gMmst);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a Standalone MM Driver.
+
+ This function is the entry point for a Standalone MM Driver.
+ This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList().
+ If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called.
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gMmRevision is not zero and SystemTable->Hdr.Revision is
+ less than _gMmRevision, then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the Standalone MM Driver.
+ @param MmSystemTable A pointer to the MM System Table.
+
+ @retval EFI_SUCCESS The Standalone MM Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gMmRevision is greater than
+ MmSystemTable->Hdr.Revision.
+ @retval Other Return value from
+ ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gMmRevision != 0) {
+ //
+ // Make sure that the MM spec revision of the platform
+ // is >= MM spec revision of the driver
+ //
+ if (MmSystemTable->Hdr.Revision < _gMmRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, MmSystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gMmst->MmHandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, MmSystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, MmSystemTable);
+ }
+
+ //
+ // Return the cumulative return status code from all of the driver entry points
+ //
+ return Status;
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
new file mode 100644
index 000000000000..de36debd74ec
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
@@ -0,0 +1,17 @@
+// /** @file
+//
+// Module entry point library for standalone MM driver
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+// Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for standalone MM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for standalone MM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
new file mode 100644
index 000000000000..a5cb42518c1b
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
@@ -0,0 +1,53 @@
+## @file
+# Module entry point library for Standalone MM drivers that dynamically updates the stack cookie.
+#
+# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016-2018, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = StandaloneMmDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
+ FILE_GUID = 28CBCD87-2FEE-4D46-BB5C-B37732BBEEB1
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmDriverEntryPoint|MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MmServicesTableLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
new file mode 100644
index 000000000000..81b9b55130e3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
@@ -0,0 +1,112 @@
+/** @file
+ Entry point library instance to a UEFI application.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Entry point to UEFI Application.
+
+ This function is the entry point for a UEFI Application. This function must call
+ ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList().
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison,
+ then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the application.
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries.
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Call the module's entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // Process destructor for all libraries.
+ //
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+
+ //
+ // Return the return status code from the driver entry point
+ //
+ return Status;
+}
+
+/**
+ Invokes the library destructors for all dependent libraries and terminates
+ the UEFI Application.
+
+ This function calls ProcessLibraryDestructorList() and the EFI Boot Service Exit()
+ with a status specified by Status.
+
+ @param Status Status returned by the application that is exiting.
+
+**/
+VOID
+EFIAPI
+Exit (
+ IN EFI_STATUS Status
+ )
+
+{
+ ProcessLibraryDestructorList (gImageHandle, gST);
+
+ gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
new file mode 100644
index 000000000000..168ce7469bb7
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI Application.
+//
+// Module entry point library for UEFI Application.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI Application"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI Application."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
new file mode 100644
index 000000000000..1a82fc498de1
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for UEFI Application that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiApplicationEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiApplication/UefiApplicationEntryPoint.uni
+ FILE_GUID = 755B9094-E5AF-4E5B-BE33-D430CDE2C5D2
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiApplicationEntryPoint|UEFI_APPLICATION
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiApplication/ApplicationEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
new file mode 100644
index 000000000000..ad17e0d1c616
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
@@ -0,0 +1,162 @@
+/** @file
+ Entry point to a EFI/DXE driver.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/LoadedImage.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gST);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver.
+
+ This function is the entry point for a DXE Driver, DXE Runtime Driver, DXE SMM Driver,
+ or UEFI Driver. This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList(). If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called. The return
+ value from ProcessModuleEntryPointList() is returned. If _gDriverUnloadImageCount
+ is greater than zero, then an unload handler must be registered for this image
+ and the unload handler must invoke ProcessModuleUnloadList().
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than
+ _gUefiDriverRevison, then return EFI_INCOMPATIBLE_VERSION.
+
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver,
+ DXE SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+ }
+
+ //
+ // Return the cummalative return status code from all of the driver entry points
+ //
+ return Status;
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in ImageHandle,
+ and SystemTable.
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver, DXE
+ SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
new file mode 100644
index 000000000000..9d820b25f063
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
new file mode 100644
index 000000000000..522bcd930c23
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
@@ -0,0 +1,68 @@
+## @file
+# Module entry point library for UEFI driver, DXE driver and SMM driver that dynamically sets the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiDriver/UefiDriverEntryPoint.uni
+ FILE_GUID = 900238F9-1421-4596-9548-A1BF58C97693
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiDriver/DriverEntryPoint.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
+
+#
+# For UEFI drivers, these architectural protocols defined in PI 1.0 spec need
+# to be appended and merged to the final dependency section.
+#
+[Depex.common.UEFI_DRIVER]
+ gEfiBdsArchProtocolGuid AND
+ gEfiCpuArchProtocolGuid AND
+ gEfiMetronomeArchProtocolGuid AND
+ gEfiMonotonicCounterArchProtocolGuid AND
+ gEfiRealTimeClockArchProtocolGuid AND
+ gEfiResetArchProtocolGuid AND
+ gEfiRuntimeArchProtocolGuid AND
+ gEfiSecurityArchProtocolGuid AND
+ gEfiTimerArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiWatchdogTimerArchProtocolGuid
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
new file mode 100644
index 000000000000..782e8bbb791a
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__stack_chk_guard)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
new file mode 100644
index 000000000000..bd290f712634
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__security_cookie)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf b/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
index 163daa67afd3..02d1c582a114 100644
--- a/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+++ b/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
@@ -31,4 +31,4 @@
[LibraryClasses]
BaseLib
DebugLib
-
+ StackCheckLib
diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.c b/MdePkg/Library/PeiRngLib/PeiRngLib.c
new file mode 100644
index 000000000000..d6c957327c6b
--- /dev/null
+++ b/MdePkg/Library/PeiRngLib/PeiRngLib.c
@@ -0,0 +1,229 @@
+/** @file
+ RNG library instance that uses the Random Number Generator (RNG) PPI to provide
+ random numbers.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/Rng.h>
+
+/**
+ Generates a random number via the NIST 800-9A algorithm. Refer to
+ http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf for more information.
+
+ @param[out] Buffer Buffer to receive the random number.
+ @param[in] BufferSize Number of bytes in Buffer.
+
+ @retval EFI_SUCCESS or underlying failure code.
+
+**/
+STATIC
+EFI_STATUS
+GenerateRandomNumberViaNist800Algorithm (
+ OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ EFI_STATUS Status;
+ RNG_PPI *RngPpi;
+
+ RngPpi = NULL;
+
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Buffer == NULL.\n", __func__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PeiServicesLocatePpi (&gEfiRngPpiGuid, 0, NULL, (VOID **)&RngPpi);
+ if (EFI_ERROR (Status) || (RngPpi == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG PPI, Status = %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm CTR-256 - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm HMAC-256 - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmRaw, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Raw - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // If all the other methods have failed, use the default method from the RngPpi
+ Status = RngPpi->GetRNG (RngPpi, NULL, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // If we get to this point, we have failed
+ DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, staus = %r\n", __func__, Status));
+
+ return Status;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT16));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT32));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT64));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Generates a 128-bit random number.
+
+ if Rand is NULL, return FALSE.
+
+ @param[out] Rand Buffer pointer to store the 128-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+ OUT UINT64 *Rand
+ )
+{
+ EFI_STATUS Status;
+
+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2 * sizeof (UINT64));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Get a GUID identifying the RNG algorithm implementation.
+
+ @param [out] RngGuid If success, contains the GUID identifying
+ the RNG algorithm implementation.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_UNSUPPORTED Not supported.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+GetRngGuid (
+ GUID *RngGuid
+ )
+{
+ // Similar to DxeRngLib, EFI_UNSUPPORTED is returned for this library instance since it is unknown
+ // which exact algorithm may be used for a given request.
+
+ return EFI_UNSUPPORTED;
+}
diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.inf b/MdePkg/Library/PeiRngLib/PeiRngLib.inf
new file mode 100644
index 000000000000..1588366eebff
--- /dev/null
+++ b/MdePkg/Library/PeiRngLib/PeiRngLib.inf
@@ -0,0 +1,41 @@
+## @file
+# PPI-based Instance of RNG (Random Number Generator) Library.
+#
+# This library instance requires a RNG PPI to be produced so that the module may use
+# it for RNG operations. A RNG PPI DEPEX will be placed on the module.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = PeiRngLib
+ MODULE_UNI_FILE = PeiRngLib.uni
+ FILE_GUID = FF240232-C25D-4277-AB81-D6B0C51F2D25
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = RngLib | PEIM
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ PeiServicesLib
+
+[Guids]
+ gEfiRngAlgorithmSp80090Ctr256Guid
+ gEfiRngAlgorithmSp80090Hash256Guid
+ gEfiRngAlgorithmSp80090Hmac256Guid
+ gEfiRngAlgorithmRaw
+
+[Sources]
+ PeiRngLib.c
+
+[Ppis]
+ gEfiRngPpiGuid ## CONSUMES
+
+[Depex]
+ gEfiRngPpiGuid
diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.uni b/MdePkg/Library/PeiRngLib/PeiRngLib.uni
new file mode 100644
index 000000000000..8aea8ab7415f
--- /dev/null
+++ b/MdePkg/Library/PeiRngLib/PeiRngLib.uni
@@ -0,0 +1,12 @@
+// @file
+// PEI Instance of the RNG (Random Number Generator) Library.
+//
+// A RngLib instance that uses the RNG PPI to provide random numbers.
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT #language en-US "Instance of the RNG Library for PEI"
+
+#string STR_MODULE_DESCRIPTION #language en-US "A library that uses the RNG PPI to provide random numbers"
diff --git a/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf b/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
index 8d11a2b35f6c..dee997aa3ca4 100644
--- a/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+++ b/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -31,4 +31,4 @@
[LibraryClasses]
DebugLib
-
+ StackCheckLib
diff --git a/MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf b/MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf
index 523a3e1d9f19..b8ebf3303d61 100644
--- a/MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf
+++ b/MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf
@@ -32,6 +32,7 @@
PcdLib
DebugLib
IoLib
+ UefiBootServicesTableLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md
index 6558c222cd24..2d3d34a8ef06 100644
--- a/MdePkg/Library/StackCheckLib/Readme.md
+++ b/MdePkg/Library/StackCheckLib/Readme.md
@@ -1,12 +1,12 @@
-# StackCheckLib
+# StackCheckLib Overview
## Table of Contents
- [StackCheckLib](#stackchecklib)
- [Table of Contents](#table-of-contents)
- [Introduction and Library Instances](#introduction-and-library-instances)
- - [StackCheckLibStaticInit](#stackchecklibstaticinit)
- - [StackCheckLibDynamicInit](#stackchecklibdynamicinit)
+ - [StackCheckLib](#stackchecklib)
+ - [DynamicStackCookieEntryPointLib](#dynamicstackcookieentrypointlib)
- [StackCheckLibNull](#stackchecklibnull)
- [How Failures are Handled](#how-failures-are-handled)
- [Debugging Stack Cookie Check Failures](#debugging-stack-cookie-check-failures)
@@ -15,44 +15,79 @@
## Introduction and Library Instances
`StackCheckLib` contains the required functionality for initializing the stack cookie
-value, checking the value, and triggering an interrupt when a mismatch occurs.
-The stack cookie is a random value placed on the stack between the stack variables
-and the return address so that continuously writing past the stack variables will
-cause the stack cookie to be overwritten. Before the function returns, the stack
-cookie value will be checked and if there is a mismatch then `StackCheckLib` handles
-the failure.
+value (based on a randomly generated value during build time), checking the value,
+and triggering an interrupt when a mismatch occurs. The stack cookie is a random value
+placed on the stack between the stack variables and the return address so that
+continuously writing past the stack variables will cause the stack cookie to be
+overwritten. Before the function returns, the stack cookie value will be checked and
+if there is a mismatch then `StackCheckLib` handles the failure.
Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack
check code is written in assembly within this library. GCC and Clang compilers
have built-in support for stack cookie checking, so this library only handles failures.
-### StackCheckLibStaticInit
-
-`StackCheckLibStaticInit` is an instance of `StackCheckLib` which does not update the
-stack cookie value for the module at runtime. It's always preferable to use
-`StackCheckLibDynamicInit` for improved security but there are cases where the stack
-cookie global cannot be written to such as in execute-in-place (XIP) modules and during
-the Cache-as-RAM (CAR) phase of the boot process. The stack cookie value is initialized
-at compile time via updates to the AutoGen process. Each module will define
-`STACK_COOKIE_VALUE` which is used for the module stack cookie value.
-
-### StackCheckLibDynamicInit
-
-This section is future work. The below is the proposed instance.
-
-`StackCheckLibDynamicInit` is an instance of `StackCheckLib` which updates the stack
-cookie value for the module at runtime. This is the preferred method for stack cookie
-initialization as it provides improved security. The stack cookie value is initialized
-at runtime by calling `GetRandomNumber32()` or `GetRandomNumber64()` to generate a random
-value via the platform's random number generator protocol. If the random number generator
-returns an error, then the value will still have the build-time randomized value to fall
-back on.
+The stack cookie value is initialized at compile time via updates to the AutoGen process.
+Each module will define `STACK_COOKIE_VALUE` which is used for the module stack cookie
+value.
+
+The entry point libraries under `MdePkg/DynamicStackCookieEntryPointLib/` update the stack
+cookie value at runtime for improved security, but there are cases where the stack cookie
+global cannot be written to such as in execute-in-place (XIP) modules and during the
+temporary RAM phase of the boot process. It is always preferable to use
+one of the dynamic stack cookie entry points when possible.
+
+### StackCheckLib
+
+`StackCheckLib` provides the stack cookie checking functionality per architecture and
+toolchain. The currently supported pairs are IA32{GCC,MSVC}, X64{GCC, MSVC},
+ARM{GCC, MSVC}, and AARCH64{GCC, MSVC}. `StackCheckLib` is agnostic as to
+whether the stack cookie was updated during build time or run time; it simply
+checks the cookie in the MSVC case and in both GCC and MSVC responds to stack
+cookie checking failures.
+
+To add support for other architectures/toolchains, additional assembly files
+should be added to `StackCheckLib.inf` and scoped to that architecture/toolchain.
+
+Note: Stack cookie failures generate exceptions and SEC and PEI_CORE may not have
+exception handlers registered. In order to safely use stack cookie checking in
+these phases, a platform should implement exception handlers because unhandled
+exceptions may lead to a hung system state. If a platform does not implement
+exception handlers in SEC and PEI_CORE, it is recommended to use `StackCheckLibNull`
+for these phases, except for development purposes.
+
+### DynamicStackCookieEntryPointLib
+
+Each EntryPoint lib under `MdePkg/DynamicStackCookieEntryPointLib/` is an instance of
+that module type entry point lib which updates the stack cookie value for the module at
+runtime. This is the preferred method for stack cookie initialization as it provides
+improved security. The stack cookie value is initialized at runtime in `_ModuleEntryPoint`
+by calling `rdrand` on x86 and `RNDR` on AARCH64. If the random number generator is not
+supported on that platform or otherwise returns an error, then the value will still have
+the build-time randomized value to fall back on.
+
+Typically, dynamic cookies cannot be used for SEC, PEI_CORE, and PEIM modules, due to
+the lack of the ability to write to globals for many architectures. If a given platform
+can write to globals during these phases, it is recommended to use the provided dynamic
+stack cookie entry point lib for those types. Note that SEC does not have a universal
+entry point, so there is no dynamic stack cookie entry point lib there.
+
+The dynamic stack cookie entry point lib is used in place of the standard entry point lib,
+e.g. for UefiDriverEntryPoint to have dynamic stack cookies, a platform would remove
+MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf from its DSC and instead
+include MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf.
+
+See the Usage section for other ways of including these libraries.
+
+Note: Standalone MM Core support for dynamic cookies for AARCH64 is currently not
+supported, due to the unique entry point mechanism there. This support will be
+added at a future date.
### StackCheckLibNull
`StackCheckLibNull` is an instance of `StackCheckLib` which does not perform any stack
cookie checks. This is useful for modules which will fail if stack cookie checks are
-inserted. Of course, this is not recommended for production code.
+inserted. Of course, this is not recommended for production code outside of
+SEC and PEI_CORE.
## How Failures are Handled
@@ -104,8 +139,9 @@ edk2 updated the tools_def to add `/GS` to VS2022 and VS2019 IA32/X64 builds and
`-fstack-protector` to GCC builds. This will cause stack cookie references to be inserted
throughout the code. Every module should have a `StackCheckLib` instance linked to satisfy
these references. So every module doesn't need to add `StackCheckLib` to the LibraryClasses
-section of the INF file, `StackCheckLib` instances should be linked as NULL in the platform
-DSC files. The only exception to this is MSVC built host-based unit tests as they will be
+section of the INF file, `StackCheckLib` is added as a dependency for each entry point lib.
+This means that custom entry point libs need to have StackCheckLib added as a dependency.
+The only exception to this is MSVC built host-based unit tests as they will be
compiled with the runtime libraries which already contain the stack cookie definitions
and will collide with `StackCheckLib`. A `StackCheckLibHostApplication.inf` is linked
by `UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc` that provides the stack
@@ -113,70 +149,75 @@ cookie functions for GCC HOST_APPLICATIONS but not for MSVC HOST_APPLICATIONS.
### Default Stack Check Library Configuration
-`MdePkg/MdeLibs.dsc.inc` links `StackCheckLibNull` for all types except SEC, HOST_APPLICATION,
-and USER_DEFINED in order to not break existing DSCs. SEC cannot be generically linked to
-because there are some SEC modules which do not link against the standard entry point
-libraries and thus do not get stack cookies inserted by the compiler. USER_DEFINED modules
-are by nature different from other modules, so we do not make any assumptions about their
-state.
+`MdePkg/MdeLibs.dsc.inc` links `StackCheckLibNull` and `StackCheckFailureLibNull` for all
+types.
As stated above, all HOST_APPLICATIONS will link against a HOST_APPLICATION specific
implementation provided in `UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc`.
-To link the rest of a platform's modules to `StackCheckLibNull`, a platform would needs
-to link it for all SEC and USER_DEFINED modules. If all of the DSC's SEC and USER_DEFINED
-modules link against the entry point libs, it would look like the following:
+### Custom Stack Check Library Configuration
+
+In order to use a different instance of StackCheckLib than `MdeLibs.dsc.inc` provides, a DSC
+should add one of the following:
+
+#### Static Stack Check Cookie Configuration
```inf
-[LibraryClasses.common.SEC, LibraryClasses.common.USER_DEFINED]
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+[Defines]
+ DEFINE CUSTOM_STACK_CHECK_LIB = STATIC
```
-If some do not, then the individual SEC/USER_DEFINED modules that do link against
-the entry point libs will need to be linked to `StackCheckLibNull`, such as below.
-This case is identifiable if a DSC is built and the linker complains the stack
-check functions are not found for a module.
+This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and instead link
+`StackCheckLib` to perform stack cookie checking on the static stack cookies, but not update
+any of the stack cookies at runtime.
+
+Because edk2 does not implement exception handling for `SEC` and `PEI_CORE`, `MdeLibs.dsc.inc`
+uses `StackCheckLibNull` for these phases always. If a platform wishes to use `StackCheckLib`
+for these phases, it should override this in its DSC, e.g.:
```inf
-UefiCpuPkg/SecCore/SecCore.inf {
- <LibraryClasses>
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
- }
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
```
-### Custom Stack Check Library Configuration
+It is recommended that a platform only do this for debugging or if they have implemented
+exception handlers for these phases.
-In order to use a different instance of StackCheckLib than `MdeLibs.dsc.inc` provides, a DSC
-should add the following:
+#### Dynamic Stack Cookie Configuration
```inf
[Defines]
- DEFINE CUSTOM_STACK_CHECK_LIB = TRUE
+ DEFINE CUSTOM_STACK_CHECK_LIB = DYNAMIC
```
-This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and rely on a DSC to
-link whichever version(s) of `StackCheckLib` it desires.
-
-It is recommended that SEC and PEI_CORE modules use `StackCheckLibNull` and pre-memory modules
-should use `StackCheckLibStaticInit`. All other modules should use `StackCheckLibDynamicInit`.
+This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and instead link
+`StackCheckLib` to perform stack cookie checking. It will also link the dynamic
+stack cookie updating versions of `DxeCoreEntryPoint`, `StandaloneMmDriverEntryPoint`,
+`UefiApplicationEntryPoint`, and `UefiDriverEntryPoint`.
-Below is an **example** of how to link the `StackCheckLib` instances in the platform DSC file
-but it may need customization based on the platform's requirements:
+Because edk2 does not implement exception handling for `SEC` and `PEI_CORE`,
+`MdeLibs.dsc.inc` uses `StackCheckLibNull` for these phases always. If a
+platform wishes to use `StackCheckLib` for these phases, it can enable static
+stack cookie checking, as documented in the previous section. Due to the fact
+that writable global variables are not supported in the `SEC` or `PEI` phases
+of execution, dynamic stack cookie checking is not supported here.
-```inf
-[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+It is recommended that a platform only do this for debugging or if they have implemented
+exception handlers for these phases.
-[LibraryClasses.common.PEIM]
- NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+Note: `StandaloneMmCoreEntryPoint` is recommended to use the dynamic stack cookie if
+possible, but as it is not supported on AARCH64 today, it is not included in MdeLibs.dsc.inc.
+Platforms should include this separately, e.g.:
-[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_CORE,
-LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.DXE_DRIVER,
-LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER, LibraryClasses.common.UEFI_DRIVER,
-LibraryClasses.common.UEFI_APPLICATION]
- NULL|MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf
+```inf
+[LibraryClasses.X64]
+ StandaloneMmCoreEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
```
+Platforms then must remove any references to these entry point libs in their DSC, so that
+the `MdeLibs.dsc.inc` versions are chosen. Alternatively, for better DSC readability,
+a platform can directly reference the dynamic stack cookie entry points.
+
### Disable Stack Check Library
If a platform would like to disable stack cookies (say for debugging purposes),
@@ -191,4 +232,14 @@ they can add the following to their DSC:
The same build options can be put in a module's INF to only disable stack cookies
for that module.
+Alternatively, a module can have the stack cookies inserted but checking disabled
+by including the following in a DSC:
+
+```inf
+SomePkg/SomeDirectory/SomeModule.inf {
+ <LibraryClasses>
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+}
+```
+
It is not recommended to disable stack cookie checking in production scenarios.
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLib.inf b/MdePkg/Library/StackCheckLib/StackCheckLib.inf
new file mode 100644
index 000000000000..417d340a851f
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLib.inf
@@ -0,0 +1,56 @@
+## @file
+# Provides the required functionality for checking the stack cookie.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckLib
+ FILE_GUID = 1C4CA056-8FEA-413C-89D2-59A7E22847B3
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StackCheckLib
+
+[Sources]
+ StackCheckLibCommonMsvc.c | MSFT
+ StackCheckLibCommonGcc.c | GCC
+
+[Sources.IA32]
+ IA32/CheckCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/CheckCookieMsvc.nasm | MSFT
+
+[Sources.IA32, Sources.X64]
+ IA32/StackCookieInterrupt.nasm
+
+[Sources.ARM]
+ Arm/StackCookieInterrupt.S |GCC
+ Arm/StackCookieInterrupt.asm |MSFT
+
+[Sources.AARCH64]
+ AArch64/StackCookieInterrupt.S |GCC
+ AArch64/StackCookieInterrupt.asm |MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ StackCheckFailureHookLib
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector
+
+[BuildOptions]
+ # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error
+ # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program
+ # optimization tries to do away with references to this symbol. The solution is to not compile the stack
+ # check libs with /GL
+ MSFT:*_*_*_CC_FLAGS = /GL-
+
+ # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where
+ # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because
+ # the compiler inserts the usage.
+ GCC:*_*_*_CC_FLAGS = -fno-lto
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
index 996d1e6d732f..cccab4212bbf 100644
--- a/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
@@ -10,6 +10,7 @@
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
+#include <Library/StackCheckLib.h>
#include <Library/StackCheckFailureHookLib.h>
/**
@@ -28,6 +29,7 @@ VOID *__stack_chk_guard = (VOID *)(UINTN)STACK_COOKIE_VALUE;
**/
VOID
+EFIAPI
__stack_chk_fail (
VOID
)
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
index 6018e3790990..449ffe6da171 100644
--- a/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
@@ -10,6 +10,7 @@
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
+#include <Library/StackCheckLib.h>
#include <Library/StackCheckFailureHookLib.h>
/**
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c
index 5c4278d60bf4..91568dee88c5 100644
--- a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c
@@ -6,6 +6,7 @@
**/
#include <Uefi.h>
+#include <Library/StackCheckLib.h>
VOID *__stack_chk_guard = (VOID *)(UINTN)0x0;
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c
index a9c26dc36b21..ff99120ad2fd 100644
--- a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c
@@ -6,5 +6,6 @@
**/
#include <Uefi.h>
+#include <Library/StackCheckLib.h>
VOID *__security_cookie = (VOID *)(UINTN)0x0;
diff --git a/MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf b/MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
new file mode 100644
index 000000000000..3052788d8216
--- /dev/null
+++ b/MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
@@ -0,0 +1,33 @@
+## @file
+# Module entry point library for Standalone MM core.
+#
+# Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPoint
+ FILE_GUID = 6D1B60B2-5DD1-4523-8F0A-607DB4D6B0CE
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources.X64]
+ X64/StandaloneMmCoreEntryPoint.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/StandaloneMmCoreEntryPoint/X64/StandaloneMmCoreEntryPoint.c b/MdePkg/Library/StandaloneMmCoreEntryPoint/X64/StandaloneMmCoreEntryPoint.c
new file mode 100644
index 000000000000..7c67c4d3c73a
--- /dev/null
+++ b/MdePkg/Library/StandaloneMmCoreEntryPoint/X64/StandaloneMmCoreEntryPoint.c
@@ -0,0 +1,69 @@
+/** @file
+ Entry point to the Standalone Mm Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/StandaloneMmCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the STANDALONE MM Core.
+
+ This function is the entry point for the STANDALONE MM Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the STANDALONE MM Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_ModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the Standalone MM Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+
+ //
+ // TODO: Set page table here?? AARCH64 has this step for some reason
+ //
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf b/MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
index a83545aac051..9fafd44d3a04 100644
--- a/MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
+++ b/MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
@@ -36,6 +36,7 @@
BaseLib
DebugLib
MmServicesTableLib
+ StackCheckLib
[Protocols]
gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf b/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
index ced65892ad11..ecd033f7f741 100644
--- a/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+++ b/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
@@ -32,4 +32,5 @@
UefiBootServicesTableLib
DebugLib
BaseLib
+ StackCheckLib
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
index 23f3010286e6..f1d1f4bc97eb 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -1882,7 +1882,7 @@ DevPathToTextHardDrive (
case SIGNATURE_TYPE_MBR:
UefiDevicePathLibCatPrint (
Str,
- L"HD(%d,%s,0x%08x,",
+ L"HD(%d,%s,0x%08x",
Hd->PartitionNumber,
L"MBR",
*((UINT32 *)(&(Hd->Signature[0])))
@@ -1892,7 +1892,7 @@ DevPathToTextHardDrive (
case SIGNATURE_TYPE_GUID:
UefiDevicePathLibCatPrint (
Str,
- L"HD(%d,%s,%g,",
+ L"HD(%d,%s,%g",
Hd->PartitionNumber,
L"GPT",
(EFI_GUID *)&(Hd->Signature[0])
@@ -1902,14 +1902,18 @@ DevPathToTextHardDrive (
default:
UefiDevicePathLibCatPrint (
Str,
- L"HD(%d,%d,0,",
+ L"HD(%d,%d,0",
Hd->PartitionNumber,
Hd->SignatureType
);
break;
}
- UefiDevicePathLibCatPrint (Str, L"0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+ if (DisplayOnly) {
+ UefiDevicePathLibCatPrint (Str, L")");
+ } else {
+ UefiDevicePathLibCatPrint (Str, L",0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+ }
}
/**
diff --git a/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf b/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
index bef65fb22631..8432fd56b921 100644
--- a/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+++ b/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
@@ -36,6 +36,7 @@
UefiBootServicesTableLib
DebugLib
BaseLib
+ StackCheckLib
[Protocols]
diff --git a/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf b/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
index 2f1224081165..8f7b26138132 100644
--- a/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+++ b/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
@@ -5,6 +5,7 @@
# Usb Hid 1.1 spec and the standard requests defined in Usb 1.1 spec.
#
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -19,6 +20,7 @@
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = UefiUsbLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+ DESTRUCTOR = UefiUsbLibDestructor
#
@@ -37,6 +39,7 @@
DebugLib
BaseMemoryLib
PcdLib
+ UefiBootServicesTableLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdUsbTransferTimeoutValue ## CONSUMES
diff --git a/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h b/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h
index 30cb4a2cb864..1c43b348b19f 100644
--- a/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h
+++ b/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h
@@ -5,6 +5,7 @@
This file includes package header files, library classes and protocol, PPI & GUID definitions.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -17,6 +18,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
#include <IndustryStandard/Usb.h>
diff --git a/MdePkg/Library/UefiUsbLib/UsbDxeLib.c b/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
index 6d46529ae2f4..f25e8097fc41 100644
--- a/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
+++ b/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
@@ -4,12 +4,16 @@
in Usb specification 9.4 section.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "UefiUsbLibInternal.h"
+static UINT8 *mConfigData = NULL;
+static EFI_USB_DEVICE_DESCRIPTOR mDeviceDescriptor;
+
/**
Get the descriptor of the specified USB device.
@@ -650,3 +654,532 @@ UsbClearEndpointHalt (
return Result;
}
+
+/**
+ Global library data initialization.
+
+ Library public functions' input is the instance of UsbIo protocol. Check if the global
+ data relevant to the UsbIo. If not, read the device and update the global data.
+
+ @param UsbIo The instance of EFI_USB_IO_PROTOCOL.
+
+ @retval EFI_SUCCESS The global data is updated.
+ @retval EFI_NOT_FOUND The UsbIo configuration was not found.
+
+**/
+static
+EFI_STATUS
+InitUsbConfigDescriptorData (
+ EFI_USB_IO_PROTOCOL *UsbIo
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_DESCRIPTOR DevDesc;
+ EFI_USB_CONFIG_DESCRIPTOR CnfDesc;
+ UINT8 ConfigNum;
+ UINT8 ConfigValue;
+ UINT32 UsbStatus;
+
+ //
+ // Get UsbIo device and configuration descriptors.
+ //
+ Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = UsbIo->UsbGetConfigDescriptor (UsbIo, &CnfDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ if (mConfigData != NULL) {
+ if ( (CompareMem (&DevDesc, &mDeviceDescriptor, sizeof (EFI_USB_DEVICE_DESCRIPTOR)) == 0)
+ && (CompareMem (&CnfDesc, mConfigData, sizeof (EFI_USB_CONFIG_DESCRIPTOR)) == 0))
+ {
+ return EFI_SUCCESS;
+ }
+
+ gBS->FreePool (mConfigData);
+ mConfigData = NULL;
+ }
+
+ CopyMem (&mDeviceDescriptor, &DevDesc, sizeof (EFI_USB_DEVICE_DESCRIPTOR));
+
+ //
+ // Examine device with multiple configurations: find configuration index of UsbIo config descriptor.
+ //
+ // Use EFI_USB_DEVICE_DESCRIPTOR.NumConfigurations to loop through configuration descriptors, match
+ // EFI_USB_CONFIG_DESCRIPTOR.ConfigurationValue to the configuration value reported by UsbIo->UsbGetConfigDescriptor.
+ // The index of the matched configuration is used in wValue of the following GET_DESCRIPTOR request.
+ //
+ ConfigValue = CnfDesc.ConfigurationValue;
+ for (ConfigNum = 0; ConfigNum < DevDesc.NumConfigurations; ConfigNum++) {
+ Status = UsbGetDescriptor (
+ UsbIo,
+ (USB_DESC_TYPE_CONFIG << 8) | ConfigNum,
+ 0,
+ sizeof (EFI_USB_CONFIG_DESCRIPTOR),
+ &CnfDesc,
+ &UsbStatus
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (CnfDesc.ConfigurationValue == ConfigValue) {
+ break;
+ }
+ }
+
+ ASSERT (ConfigNum < DevDesc.NumConfigurations);
+ if (ConfigNum == DevDesc.NumConfigurations) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // ConfigNum has zero based index of the configuration that UsbIo belongs to. Use this index to retrieve
+ // full configuration descriptor data.
+ //
+ Status = gBS->AllocatePool (EfiBootServicesData, CnfDesc.TotalLength, (VOID **)&mConfigData);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = UsbGetDescriptor (
+ UsbIo,
+ (USB_DESC_TYPE_CONFIG << 8) | ConfigNum,
+ 0,
+ CnfDesc.TotalLength,
+ mConfigData,
+ &UsbStatus
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Find descriptor of a given type within data area pointed by mConfigData.
+
+ The following are the assumptions of the configuration descriptor layout:
+ - mConfigData is populated with the configuration data that contains USB interface referenced by UsbIo.
+ - Endpoint may have only one class specific descriptor that immediately follows the endpoint descriptor.
+
+ @param[in] UsbIo A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] DescType Type of descriptor to look for.
+ @param[in] Setting Interface alternate setting.
+ @param[in] Index Index of the descriptor. This descriptor index is used to find a specific
+ descriptor (only for endpoint descriptors and class specific interface descriptors)
+ when several descriptors of the same type are implemented in a device. For other
+ descriptor types, a descriptor index of zero must be used.
+ @param[out] Data A pointer to the caller allocated Descriptor.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_UNSUPPORTED Setting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of descriptors of the requested type in this
+ interface.
+**/
+static
+EFI_STATUS
+FindUsbDescriptor (
+ EFI_USB_IO_PROTOCOL *UsbIo,
+ UINT8 DescType,
+ UINT16 Setting,
+ UINTN Index,
+ VOID **Data
+ )
+{
+ EFI_USB_INTERFACE_DESCRIPTOR IntfDesc;
+ EFI_STATUS Status;
+ UINT8 *BufferPtr;
+ UINT8 *BufferEnd;
+ UINT8 *ConfigEnd;
+ UINTN Idx;
+
+ //
+ // Find the interface descriptor referenced by UsbIo in the current configuration
+ //
+ Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IntfDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ ConfigEnd = mConfigData + ((EFI_USB_CONFIG_DESCRIPTOR *)mConfigData)->TotalLength;
+
+ for (BufferPtr = mConfigData; BufferPtr < ConfigEnd; BufferPtr += BufferPtr[0]) {
+ if (BufferPtr[1] == USB_DESC_TYPE_INTERFACE) {
+ if ((BufferPtr[2] == IntfDesc.InterfaceNumber) && (BufferPtr[3] == (UINT8)Setting)) {
+ break;
+ }
+ }
+ }
+
+ if (BufferPtr >= ConfigEnd) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Found the beginning of the interface, find the ending
+ //
+ for (BufferEnd = BufferPtr + BufferPtr[0]; BufferEnd < ConfigEnd; BufferEnd += BufferEnd[0]) {
+ if (BufferEnd[1] == USB_DESC_TYPE_INTERFACE) {
+ break;
+ }
+ }
+
+ Idx = 0;
+
+ if (DescType == USB_DESC_TYPE_INTERFACE) {
+ *Data = BufferPtr;
+ return EFI_SUCCESS;
+ }
+
+ if ((DescType == USB_DESC_TYPE_ENDPOINT) || (DescType == USB_DESC_TYPE_CS_ENDPOINT)) {
+ while (BufferPtr < BufferEnd) {
+ BufferPtr += BufferPtr[0];
+ if (BufferPtr[1] == USB_DESC_TYPE_ENDPOINT) {
+ if (Idx == Index) {
+ if (DescType == USB_DESC_TYPE_CS_ENDPOINT) {
+ BufferPtr += BufferPtr[0];
+ if (BufferPtr[1] != USB_DESC_TYPE_CS_ENDPOINT) {
+ break;
+ }
+ }
+
+ *Data = BufferPtr;
+ return EFI_SUCCESS;
+ }
+
+ Idx++;
+ }
+ }
+ }
+
+ if (DescType == USB_DESC_TYPE_CS_INTERFACE) {
+ while (BufferPtr < BufferEnd) {
+ BufferPtr += BufferPtr[0];
+ if (BufferPtr[1] == USB_DESC_TYPE_CS_INTERFACE) {
+ if (Idx == Index) {
+ *Data = BufferPtr;
+ return EFI_SUCCESS;
+ }
+
+ Idx++;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Retrieve the number of class specific interface descriptors.
+
+ @param[in] Data A pointer to the USB interface descriptor that may contain class code descriptors.
+
+ @retval UINT8 Number of the class code interface descriptors.
+
+**/
+static
+UINT8
+FindNumberOfCsInterfaces (
+ VOID *Data
+ )
+{
+ UINT8 *Buffer;
+ UINT8 *ConfigEnd;
+ UINT8 Index;
+
+ Buffer = Data;
+ ConfigEnd = mConfigData + ((EFI_USB_CONFIG_DESCRIPTOR *)mConfigData)->TotalLength;
+
+ Index = 0;
+
+ for (Buffer += Buffer[0]; Buffer < ConfigEnd; Buffer += Buffer[0]) {
+ if (Buffer[1] == USB_DESC_TYPE_INTERFACE) {
+ break;
+ }
+
+ if (Buffer[1] == USB_DESC_TYPE_CS_INTERFACE) {
+ Index++;
+ }
+ }
+
+ return Index;
+}
+
+/**
+ Retrieve the interface descriptor details from the interface setting.
+
+ This is an extended version of UsbIo->GetInterfaceDescriptor. It returns the interface
+ descriptor for an alternate setting of the interface without executing SET_INTERFACE
+ transfer. It also returns the number of class specific interfaces.
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[out] Descriptor The caller allocated buffer to return the contents of the Interface descriptor.
+ @param[out] CsInterfaceNumber Number of class specific interfaces for this interface setting.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER Descriptor or CsInterfaceNumber is NULL.
+ @retval EFI_UNSUPPORTED AlternateSetting is greater than the number of alternate settings in this interface.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetInterfaceDescriptorSetting (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ OUT EFI_USB_INTERFACE_DESCRIPTOR *Descriptor,
+ OUT UINTN *CsInterfacesNumber
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ EFI_TPL OldTpl;
+
+ if ((Descriptor == NULL) || (CsInterfacesNumber == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = InitUsbConfigDescriptorData (This);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = FindUsbDescriptor (This, USB_DESC_TYPE_INTERFACE, AlternateSetting, 0, &Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ *CsInterfacesNumber = FindNumberOfCsInterfaces (Data);
+ CopyMem (Descriptor, Data, sizeof (EFI_USB_INTERFACE_DESCRIPTOR));
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Retrieve the endpoint descriptor from the interface setting.
+
+ This is an extended version of UsbIo->GetEndpointDescriptor. It returns the endpoint
+ descriptor for an alternate setting of a given interface.
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ Note: The total number of endpoints can be retrieved from the interface descriptor
+ returned by EDKII_USBIO_EXT_GET_INTERFACE_DESCRIPTOR function.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Index of the endpoint to retrieve. The valid range is 0..15.
+ @param[out] Descriptor A pointer to the caller allocated USB Interface Descriptor.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER Descriptor is NULL.
+ @retval EFI_UNSUPPORTED AlternateSetting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of endpoints in this interface.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetEndpointDescriptorSetting (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ OUT EFI_USB_ENDPOINT_DESCRIPTOR *Descriptor
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ EFI_TPL OldTpl;
+
+ if (Descriptor == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = InitUsbConfigDescriptorData (This);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = FindUsbDescriptor (This, USB_DESC_TYPE_ENDPOINT, AlternateSetting, Index, &Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ CopyMem (Descriptor, Data, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Retrieve class specific interface descriptor.
+
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Zero-based index of the class specific interface.
+ @param[in][out] BufferSize On input, the size in bytes of the return Descriptor buffer.
+ On output the size of data returned in Descriptor.
+ @param[out] Descriptor The buffer to return the contents of the class specific interface descriptor. May
+ be NULL with a zero BufferSize in order to determine the size buffer needed.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL.
+ Buffer is NULL and *BufferSize is not zero.
+ @retval EFI_UNSUPPORTED AlternateSetting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of class specific interfaces.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been updated with the size
+ needed to complete the request.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetCsInterfaceDescriptor (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINT8 DescLength;
+ EFI_TPL OldTpl;
+
+ if ((BufferSize == NULL) || ((Buffer == NULL) && (*BufferSize != 0))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = InitUsbConfigDescriptorData (This);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = FindUsbDescriptor (This, USB_DESC_TYPE_CS_INTERFACE, AlternateSetting, Index, &Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ DescLength = ((UINT8 *)Data)[0];
+
+ if ((Buffer == NULL) || (DescLength > *BufferSize)) {
+ *BufferSize = DescLength;
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+
+ CopyMem (Buffer, Data, DescLength);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Retrieve class specific endpoint descriptor.
+
+ AlternateSetting parameter is the zero-based interface descriptor index that is used in USB
+ interface descriptor as USB_INTERFACE_DESCRIPTOR.AlternateSetting.
+
+ @param[in] This A pointer to the EFI_USB_IO_PROTOCOL instance.
+ @param[in] AlternateSetting Interface alternate setting.
+ @param[in] Index Zero-based index of the non-zero endpoint.
+ @param[in][out] BufferSize On input, the size in bytes of the return Descriptor buffer.
+ On output the size of data returned in Descriptor.
+ @param[out] Descriptor The buffer to return the contents of the class specific endpoint descriptor. May
+ be NULL with a zero BufferSize in order to determine the size buffer needed.
+
+ @retval EFI_SUCCESS Output parameters were updated successfully.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL.
+ Buffer is NULL and *BufferSize is not zero.
+ @retval EFI_UNSUPPORTED AlternateSetting is greater than the number of alternate settings in this interface.
+ @retval EFI_NOT_FOUND Index is greater than the number of endpoints in this interface.
+ Endpoint does not have class specific endpoint descriptor.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been updated with the size
+ needed to complete the request.
+ @retval EFI_DEVICE_ERROR Error reading device data.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetCsEndpointDescriptor (
+ IN EFI_USB_IO_PROTOCOL *This,
+ IN UINT16 AlternateSetting,
+ IN UINTN Index,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINT8 DescLength;
+ EFI_TPL OldTpl;
+
+ if ((BufferSize == NULL) || ((Buffer == NULL) && (*BufferSize != 0))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = InitUsbConfigDescriptorData (This);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = FindUsbDescriptor (This, USB_DESC_TYPE_CS_ENDPOINT, AlternateSetting, Index, &Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ DescLength = ((UINT8 *)Data)[0];
+
+ if ((Buffer == NULL) || (DescLength > *BufferSize)) {
+ *BufferSize = DescLength;
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+
+ CopyMem (Buffer, Data, DescLength);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Destructor frees memory which was allocated by the library functions.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+ @param SystemTable The system table.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiUsbLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (mConfigData != NULL) {
+ gBS->FreePool (mConfigData);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc
index acb937e200c1..a8b929de8b86 100644
--- a/MdePkg/MdeLibs.dsc.inc
+++ b/MdePkg/MdeLibs.dsc.inc
@@ -11,6 +11,14 @@
#
##
+[Defines]
+!ifndef CUSTOM_STACK_CHECK_LIB
+ # The DSC parser will set any unset macros to 0. Then, below when we check for STATIC or DYNAMIC, even if we couch
+ # that in a !ifdef CUSTOM_STACK_CHECK_LIB, the parser will issue a warning that we are comparing a boolean (0) against
+ # a string, which will always fail. So we set it to a dummy value here.
+ DEFINE CUSTOM_STACK_CHECK_LIB = NONE
+!endif
+
[LibraryClasses]
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
@@ -22,13 +30,35 @@
MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
-!ifndef CUSTOM_STACK_CHECK_LIB
+!if $(CUSTOM_STACK_CHECK_LIB) == STATIC
+ # To only use the static stack cookie, we just include the checking functionality.
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
+!elseif $(CUSTOM_STACK_CHECK_LIB) == DYNAMIC
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
+
+ # To use the dynamic stack cookie, we need to include the entry point libraries that will set up the stack cookie.
+ # Typically, PeiCore and PEIMs will not use dynamic stack cookies, so they are not included generally.
+ # If dynamic stack cookies are not enabled, we do not setup the entry points, as the existing behavior was
+ # for a platform to define them.
+ # StandaloneMmCoreEntryPoint is not included here because support dynamic stack cookies is not available for
+ # AARCH64 here. X64 platforms should include the DynamicStackCookieEntryPointLib in their DSC file.
+ DxeCoreEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
+ StandaloneMmDriverEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
+ UefiDriverEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
+
+!else
# If CUSTOM_STACK_CHECK_LIB is set, MdeLibs.dsc.inc will not link StackCheckLibNull and it is expected that the
# DSC being built is providing it's own implementation of StackCheckLib.
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
-
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
!endif
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ # edk2 does not implement exception handling for SEC and PEI_CORE, so StackCheckLibNull is used, as failing
+ # stack cookies will generate an exception, which if unhandled can lead to a hung system state. If a platform
+ # implements exception handling for SEC and PEI_CORE, it can use StackCheckLib for these phases in its DSC.
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent the ARM/AARCH64 compilers from inserting generic intrinsic functions.
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index b86a3595e108..a509b51cf2a3 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -11,6 +11,7 @@
# Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
# Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -307,6 +308,10 @@
#
StackCheckFailureHookLib|Include/Library/StackCheckFailureHookLib.h
+ ## @libraryclass Provides stack cookie checking functionality
+ #
+ StackCheckLib|Include/Library/StackCheckLib.h
+
[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
## @libraryclass Provides services to generate random number.
#
@@ -339,6 +344,11 @@
## @libraryclass Provides function to support TDX processing.
TdxLib|Include/Library/TdxLib.h
+[LibraryClasses.X64]
+ ## @libraryclass Defines a set of interfaces for the MM core entrypoint. The ARM/AARCH64 version lives in ArmPkg
+ #
+ StandaloneMmCoreEntryPoint|Include/Library/StandaloneMmCoreEntryPoint.h
+
[LibraryClasses.RISCV64]
## @libraryclass Provides function to make ecalls to SBI
BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
@@ -629,6 +639,7 @@
gEfiCertSha384Guid = { 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1 }}
gEfiCertSha512Guid = { 0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a }}
gEfiCertPkcs7Guid = { 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7 }}
+ gEfiCertSm3Guid = { 0x57347f87, 0x7a9b, 0x403a, {0xb9, 0x3c, 0xdc, 0x4a, 0xfb, 0x7a, 0x0e, 0xbc }}
## Include/Protocol/Hash.h
gEfiHashAlgorithmSha1NoPadGuid = { 0x24c5dc2f, 0x53e2, 0x40ca, { 0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b }}
@@ -644,6 +655,7 @@
gEfiCertX509Sha256Guid = { 0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed }}
gEfiCertX509Sha384Guid = { 0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b }}
gEfiCertX509Sha512Guid = { 0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d }}
+ gEfiCertX509Sm3Guid = { 0x60d807e5, 0x10b4, 0x49a9, {0x93, 0x31, 0xe4, 0x04, 0x37, 0x88, 0x8d, 0x37 }}
## Include/Protocol/Rng.h
gEfiRngAlgorithmSp80090Hash256Guid = { 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 }}
@@ -702,6 +714,7 @@
gEfiBootManagerPolicyConsoleGuid = { 0xCAB0E94C, 0xE15F, 0x11E3, { 0x91, 0x8D, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA }}
gEfiBootManagerPolicyNetworkGuid = { 0xD04159DC, 0xE15F, 0x11E3, { 0xB2, 0x61, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA }}
gEfiBootManagerPolicyConnectAllGuid = { 0x113B2126, 0xFC8A, 0x11E3, { 0xBD, 0x6C, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA }}
+ gEfiBootManagerPolicyStorageGuid = { 0xCD68FE79, 0xD3CB, 0x436E, { 0xA8, 0x50, 0xF4, 0x43, 0xC8, 0x8C, 0xFB, 0x49 }}
## Include/Protocol/DevicePath.h
gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }}
@@ -1082,6 +1095,9 @@
## Include/Ppi/DelayedDispatch.h
gEfiPeiDelayedDispatchPpiGuid = { 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6 }}
+ ## Include/Ppi/Rng.h
+ gEfiRngPpiGuid = { 0xeaed0a7e, 0x1a70, 0x4c2b, { 0x85, 0x58, 0x37, 0x17, 0x74, 0x56, 0xd8, 0x06 }}
+
[Protocols]
## Include/Protocol/MemoryAccept.h
gEdkiiMemoryAcceptProtocolGuid = { 0x38c74800, 0x5590, 0x4db4, { 0xa0, 0xf3, 0x67, 0x5d, 0x9b, 0x8e, 0x80, 0x26 }}
@@ -2222,8 +2238,15 @@
# @ValidList 0x80000003 | 0x3040003
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeDriverEnd|0x3040003|UINT32|0x30001014
- ## This flag is used to control build time optimization based on debug print level.
- # Its default value is 0xFFFFFFFF to expose all debug print level.
+ ## This flag is used to control fixed-at-build optimization of DEBUG_PRINT macros.<BR><BR>
+ # The default value is 0xFFFFFFFF, meaning that DEBUG_PRINT (...) always evaluates
+ # the macro arguments and always invokes DebugPrint (...). If you want to optimize
+ # messages, you might set this to a more restrictive value like 0x80000002 (optimize-out
+ # everything except errors and warnings).<BR><BR>
+ # This flag is consumed by DebugLib's DebugPrintLevelEnabled (Level) function. The
+ # DEBUG_PRINT (Level, Format, ...) macro in DebugLib.h calls DebugPrintLevelEnabled (Level)
+ # to filter the output, and most implementations of DebugPrintLevelEnabled (Level) simply
+ # return (Level & PcdFixedDebugPrintErrorLevel) != 0.<BR><BR>
# BIT0 - Initialization message.<BR>
# BIT1 - Warning message.<BR>
# BIT2 - Load Event message.<BR>
@@ -2307,17 +2330,30 @@
gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000|UINT32|0x00000004
## The mask is used to control DebugLib behavior.<BR><BR>
- # BIT0 - Enable Debug Assert.<BR>
- # BIT1 - Enable Debug Print.<BR>
- # BIT2 - Enable Debug Code.<BR>
- # BIT3 - Enable Clear Memory.<BR>
- # BIT4 - Enable BreakPoint as ASSERT.<BR>
- # BIT5 - Enable DeadLoop as ASSERT.<BR>
+ # Note that if the MDEPKG_NDEBUG macro is defined, the ASSERT***, CR, and DEBUG macros will be
+ # no-ops regardless of this value.<BR>
+ # Note that MDEPKG_NDEBUG does not affect DEBUG_PRINT.<BR><BR>
+ # BIT0 - ASSERT_ENABLED: Enable the ASSERT*** and CR macros.<BR>
+ # BIT1 - PRINT_ENABLED: Enable the DEBUG macro (does not affect the DEBUG_PRINT macro).<BR>
+ # BIT2 - CODE_ENABLED: Enable the DEBUG_CODE_BEGIN macro.<BR>
+ # BIT3 - CLEAR_MEMORY_ENABLED: Enable the DEBUG_CLEAR_MEMORY macro.<BR>
+ # BIT4 - ASSERT_BREAKPOINT_ENABLED: Enable BreakPoint for failed ASSERT.<BR>
+ # BIT5 - ASSERT_DEADLOOP_ENABLED: Enable DeadLoop for failed ASSERT.<BR>
# @Prompt Debug Property.
# @Expression 0x80000002 | (gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask & 0xC0) == 0
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0|UINT8|0x00000005
- ## This flag is used to control the print out Debug message.<BR><BR>
+ ## This flag is used to filter the output of the DEBUG_PRINT macro and DebugPrint functions.<BR><BR>
+ # The default value is 0x80000000, meaning that DebugPrint returns immediately for anything
+ # except errors. You might set this to a value like 0x80000002 to also enable warnings.<BR><BR>
+ # This flag is consumed by the BaseDebugPrintErrorLevelLib implementation of
+ # GetDebugPrintErrorLevel (). DebugLib's DebugPrint (Level, ...) functions return immediately if
+ # (GetDebugPrintErrorLevel() & Level) == 0. Other implementations of DebugPrintErrorLevelLib
+ # may provide different definitions of GetDebugPrintErrorLevel ().<BR><BR>
+ # Note that the DEBUG_PRINT macro also uses PcdFixedDebugPrintErrorLevel to determine whether
+ # or not it calls the DebugPrint function, so your message level needs to be enabled in both
+ # PcdFixedDebugPrintErrorLevel and PcdDebugPrintErrorLevel settings for the DEBUG_PRINT macro
+ # to work.<BR><BR>
# BIT0 - Initialization message.<BR>
# BIT1 - Warning message.<BR>
# BIT2 - Load Event message.<BR>
@@ -2433,6 +2469,34 @@
# @Prompt Time-out for a response, internal
gEfiMdePkgTokenSpaceGuid.PcdIpmiSsifResponseRetryIntervalMicrosecond|60000|UINT32|0x00000036
+ ## This is requester's Software IDs for IPMI Serial.
+ # This byte is 20h when the BMC is the requester (section 14.4.3).
+ # @Prompt IPMI Serial requester Software ID
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialRequesterAddress|0x20|UINT8|0x00000050
+
+ ## This is responder's Software IDs for IPMI Serial.
+ # This byte is 20h when the BMC is the responder (section 14.4.3).
+ # @Prompt IPMI Serial responder Software ID
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialResponderAddress|0x20|UINT8|0x00000051
+
+ ## This is requester's LUN for IPMI Serial.
+ # @Prompt IPMI Serial requester LUN
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialRequesterLun|0x0|UINT8|0x00000052
+
+ ## This is responder's LUN for IPMI Serial.
+ # @Prompt IPMI Serial responder LUN
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialResponderLun|0x0|UINT8|0x00000053
+
+ ## This is the maximum number of IPMI Serial request retries.
+ # The IPMB specification specified min value is 5 (section 4).
+ # @Prompt Number of IPMI Serial request retries.
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialRequestRetryCount|5|UINT8|0x00000054
+
+ ## This is the required interval for each IPMI request retry.
+ # The IPMB specification specified min value is 60ms (section 4).
+ # @Prompt Time-out for a request, internal
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiSerialRequestRetryInterval|60000|UINT32|0x00000055
+
[PcdsFixedAtBuild.AARCH64, PcdsPatchableInModule.AARCH64]
## GUID identifying the Rng algorithm implemented by CPU instruction.
# @Prompt CPU Rng algorithm's GUID.
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index fab2dd8a9d74..5cd98a486ef3 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -138,10 +138,15 @@
MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf
MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
+ MdePkg/Library/PeiRngLib/PeiRngLib.inf
MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
- MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+ MdePkg/Library/StackCheckLib/StackCheckLib.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
#
@@ -191,6 +196,10 @@
MdePkg/Library/MipiSysTLib/MipiSysTLib.inf
MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf
+[Components.X64]
+ MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
+ MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
+
[Components.EBC]
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
diff --git a/MdePkg/Test/MdePkgHostTest.dsc b/MdePkg/Test/MdePkgHostTest.dsc
index 0fc0432fc810..1c35e3f2b0a9 100644
--- a/MdePkg/Test/MdePkgHostTest.dsc
+++ b/MdePkg/Test/MdePkgHostTest.dsc
@@ -52,5 +52,6 @@
MdePkg/Test/Mock/Library/GoogleTest/MockCpuLib/MockCpuLib.inf
MdePkg/Test/Mock/Library/GoogleTest/MockPciSegmentLib/MockPciSegmentLib.inf
MdePkg/Test/Mock/Library/GoogleTest/MockReportStatusCodeLib/MockReportStatusCodeLib.inf
+ MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.inf
MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf
diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockSafeIntLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockSafeIntLib.h
new file mode 100644
index 000000000000..d5de86754fd5
--- /dev/null
+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockSafeIntLib.h
@@ -0,0 +1,1001 @@
+/** @file
+ Google Test mocks for the SafeInt Library
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MOCK_SAFE_INT_LIB_H_
+#define MOCK_SAFE_INT_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/FunctionMockLib.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/SafeIntLib.h>
+}
+
+struct MockSafeIntLib {
+ MOCK_INTERFACE_DECLARATION (MockSafeIntLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToUint8,
+ (
+ IN INT8 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToChar8,
+ (
+ IN INT8 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToUint16,
+ (
+ IN INT8 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToUint32,
+ (
+ IN INT8 Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToUintn,
+ (
+ IN INT8 Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8ToUint64,
+ (
+ IN INT8 Operand,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint8ToInt8,
+ (
+ IN UINT8 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint8ToChar8,
+ (
+ IN UINT8 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToInt8,
+ (
+ IN INT16 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToChar8,
+ (
+ IN INT16 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToUint8,
+ (
+ IN INT16 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToUint16,
+ (
+ IN INT16 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToUint32,
+ (
+ IN INT16 Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToUintn,
+ (
+ IN INT16 Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16ToUint64,
+ (
+ IN INT16 Operand,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16ToInt8,
+ (
+ IN UINT16 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16ToChar8,
+ (
+ IN UINT16 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16ToUint8,
+ (
+ IN UINT16 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16ToInt16,
+ (
+ IN UINT16 Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToInt8,
+ (
+ IN INT32 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToChar8,
+ (
+ IN INT32 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToUint8,
+ (
+ IN INT32 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToInt16,
+ (
+ IN INT32 Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToUint16,
+ (
+ IN INT32 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToUint32,
+ (
+ IN INT32 Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToUintn,
+ (
+ IN INT32 Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32ToUint64,
+ (
+ IN INT32 Operand,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToInt8,
+ (
+ IN UINT32 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToChar8,
+ (
+ IN UINT32 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToUint8,
+ (
+ IN UINT32 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToInt16,
+ (
+ IN UINT32 Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToUint16,
+ (
+ IN UINT32 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToInt32,
+ (
+ IN UINT32 Operand,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32ToIntn,
+ (
+ IN UINT32 Operand,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToInt8,
+ (
+ IN INTN Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToChar8,
+ (
+ IN INTN Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToUint8,
+ (
+ IN INTN Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToInt16,
+ (
+ IN INTN Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToUint16,
+ (
+ IN INTN Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToInt32,
+ (
+ IN INTN Operand,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToUint32,
+ (
+ IN INTN Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToUintn,
+ (
+ IN INTN Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnToUint64,
+ (
+ IN INTN Operand,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToInt8,
+ (
+ IN UINTN Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToChar8,
+ (
+ IN UINTN Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToUint8,
+ (
+ IN UINTN Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToInt16,
+ (
+ IN UINTN Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToUint16,
+ (
+ IN UINTN Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToInt32,
+ (
+ IN UINTN Operand,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToUint32,
+ (
+ IN UINTN Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToIntn,
+ (
+ IN UINTN Operand,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnToInt64,
+ (
+ IN UINTN Operand,
+ OUT INT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToInt8,
+ (
+ IN INT64 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToChar8,
+ (
+ IN INT64 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToUint8,
+ (
+ IN INT64 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToInt16,
+ (
+ IN INT64 Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToUint16,
+ (
+ IN INT64 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToInt32,
+ (
+ IN INT64 Operand,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToUint32,
+ (
+ IN INT64 Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToIntn,
+ (
+ IN INT64 Operand,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToUintn,
+ (
+ IN INT64 Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64ToUint64,
+ (
+ IN INT64 Operand,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToInt8,
+ (
+ IN UINT64 Operand,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToChar8,
+ (
+ IN UINT64 Operand,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToUint8,
+ (
+ IN UINT64 Operand,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToInt16,
+ (
+ IN UINT64 Operand,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToUint16,
+ (
+ IN UINT64 Operand,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToInt32,
+ (
+ IN UINT64 Operand,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToUint32,
+ (
+ IN UINT64 Operand,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToIntn,
+ (
+ IN UINT64 Operand,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToUintn,
+ (
+ IN UINT64 Operand,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64ToInt64,
+ (
+ IN UINT64 Operand,
+ OUT INT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint8Add,
+ (
+ IN UINT8 Augend,
+ IN UINT8 Addend,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16Add,
+ (
+ IN UINT16 Augend,
+ IN UINT16 Addend,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32Add,
+ (
+ IN UINT32 Augend,
+ IN UINT32 Addend,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnAdd,
+ (
+ IN UINTN Augend,
+ IN UINTN Addend,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64Add,
+ (
+ IN UINT64 Augend,
+ IN UINT64 Addend,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint8Sub,
+ (
+ IN UINT8 Minuend,
+ IN UINT8 Subtrahend,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16Sub,
+ (
+ IN UINT16 Minuend,
+ IN UINT16 Subtrahend,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32Sub,
+ (
+ IN UINT32 Minuend,
+ IN UINT32 Subtrahend,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnSub,
+ (
+ IN UINTN Minuend,
+ IN UINTN Subtrahend,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64Sub,
+ (
+ IN UINT64 Minuend,
+ IN UINT64 Subtrahend,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint8Mult,
+ (
+ IN UINT8 Multiplicand,
+ IN UINT8 Multiplier,
+ OUT UINT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint16Mult,
+ (
+ IN UINT16 Multiplicand,
+ IN UINT16 Multiplier,
+ OUT UINT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint32Mult,
+ (
+ IN UINT32 Multiplicand,
+ IN UINT32 Multiplier,
+ OUT UINT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUintnMult,
+ (
+ IN UINTN Multiplicand,
+ IN UINTN Multiplier,
+ OUT UINTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeUint64Mult,
+ (
+ IN UINT64 Multiplicand,
+ IN UINT64 Multiplier,
+ OUT UINT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8Add,
+ (
+ IN INT8 Augend,
+ IN INT8 Addend,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeChar8Add,
+ (
+ IN CHAR8 Augend,
+ IN CHAR8 Addend,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16Add,
+ (
+ IN INT16 Augend,
+ IN INT16 Addend,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32Add,
+ (
+ IN INT32 Augend,
+ IN INT32 Addend,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnAdd,
+ (
+ IN INTN Augend,
+ IN INTN Addend,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64Add,
+ (
+ IN INT64 Augend,
+ IN INT64 Addend,
+ OUT INT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8Sub,
+ (
+ IN INT8 Minuend,
+ IN INT8 Subtrahend,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeChar8Sub,
+ (
+ IN CHAR8 Minuend,
+ IN CHAR8 Subtrahend,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16Sub,
+ (
+ IN INT16 Minuend,
+ IN INT16 Subtrahend,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32Sub,
+ (
+ IN INT32 Minuend,
+ IN INT32 Subtrahend,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnSub,
+ (
+ IN INTN Minuend,
+ IN INTN Subtrahend,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64Sub,
+ (
+ IN INT64 Minuend,
+ IN INT64 Subtrahend,
+ OUT INT64 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt8Mult,
+ (
+ IN INT8 Multiplicand,
+ IN INT8 Multiplier,
+ OUT INT8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeChar8Mult,
+ (
+ IN CHAR8 Multiplicand,
+ IN CHAR8 Multiplier,
+ OUT CHAR8 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt16Mult,
+ (
+ IN INT16 Multiplicand,
+ IN INT16 Multiplier,
+ OUT INT16 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt32Mult,
+ (
+ IN INT32 Multiplicand,
+ IN INT32 Multiplier,
+ OUT INT32 *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeIntnMult,
+ (
+ IN INTN Multiplicand,
+ IN INTN Multiplier,
+ OUT INTN *Result
+ )
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ RETURN_STATUS,
+ SafeInt64Mult,
+ (
+ IN INT64 Multiplicand,
+ IN INT64 Multiplier,
+ OUT INT64 *Result
+ )
+ );
+};
+
+#endif
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.cpp
new file mode 100644
index 000000000000..92367b657ad8
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.cpp
@@ -0,0 +1,116 @@
+/** @file
+ Google Test mocks for SafeIntLib
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <GoogleTest/Library/MockSafeIntLib.h>
+
+MOCK_INTERFACE_DEFINITION (MockSafeIntLib);
+
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8ToUint64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint8ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint8ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16ToUint64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16ToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32ToUint64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToInt32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32ToIntn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToInt32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnToUint64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToInt32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToIntn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnToInt64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToInt32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToIntn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64ToUint64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToInt8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToChar8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToUint8, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToInt16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToUint16, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToInt32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToUint32, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToIntn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToUintn, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64ToInt64, 2, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint8Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnAdd, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint8Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnSub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint8Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint16Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint32Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUintnMult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeUint64Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeChar8Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnAdd, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64Add, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeChar8Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnSub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64Sub, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt8Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeChar8Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt16Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt32Mult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeIntnMult, 3, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockSafeIntLib, SafeInt64Mult, 3, EFIAPI);
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.inf b/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.inf
new file mode 100644
index 000000000000..1a3806d5a50d
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockSafeIntLib/MockSafeIntLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Mock implementation of the SafeInt library
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MockSafeIntLib
+ FILE_GUID = 318369D7-D942-47FC-A4BC-F881DEE5085E
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SafeIntLib
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MockSafeIntLib.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /EHsc