summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/efi/Library
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/ipxe/efi/Library')
-rw-r--r--src/include/ipxe/efi/Library/BaseLib.h317
1 files changed, 272 insertions, 45 deletions
diff --git a/src/include/ipxe/efi/Library/BaseLib.h b/src/include/ipxe/efi/Library/BaseLib.h
index 16ea35cd2..30e2c76b1 100644
--- a/src/include/ipxe/efi/Library/BaseLib.h
+++ b/src/include/ipxe/efi/Library/BaseLib.h
@@ -7,6 +7,7 @@ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
+Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -16,6 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define __BASE_LIB__
FILE_LICENCE ( BSD2_PATENT );
+FILE_SECBOOT ( PERMITTED );
//
// Definitions for architecture-specific types
@@ -78,26 +80,6 @@ typedef struct {
#endif // defined (MDE_CPU_EBC)
-#if defined (MDE_CPU_ARM)
-
-typedef struct {
- UINT32 R3; ///< A copy of R13.
- UINT32 R4;
- UINT32 R5;
- UINT32 R6;
- UINT32 R7;
- UINT32 R8;
- UINT32 R9;
- UINT32 R10;
- UINT32 R11;
- UINT32 R12;
- UINT32 R14;
-} BASE_LIBRARY_JUMP_BUFFER;
-
-#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4
-
-#endif // defined (MDE_CPU_ARM)
-
#if defined (MDE_CPU_AARCH64)
typedef struct {
// GP regs
@@ -128,6 +110,92 @@ typedef struct {
#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+/**
+ Reads the current value of CNTPCT_EL0 register.
+
+ Reads and returns the current value of CNTPCT_EL0.
+ This function is only available on AARCH64.
+
+ @return The current value of CNTPCT_EL0
+**/
+UINT64
+EFIAPI
+ArmReadCntPctReg (
+ VOID
+ );
+
+//
+// Bit shifts for the ID_AA64ISAR0_EL1 register.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_SHIFT (4U)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT (8U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT (12U)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT (16U)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT (20U)
+#define ARM_ID_AA64ISAR0_EL1_RDM_SHIFT (28U)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT (32U)
+#define ARM_ID_AA64ISAR0_EL1_SM3_SHIFT (36U)
+#define ARM_ID_AA64ISAR0_EL1_SM4_SHIFT (40U)
+#define ARM_ID_AA64ISAR0_EL1_DP_SHIFT (44U)
+#define ARM_ID_AA64ISAR0_EL1_FHM_SHIFT (48U)
+#define ARM_ID_AA64ISAR0_EL1_TS_SHIFT (52U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_SHIFT (56U)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT (60U)
+
+//
+// Bit masks for the ID_AA64ISAR0_EL1 fields.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_RDM_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SM3_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SM4_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_DP_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_FHM_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_TS_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_TLB_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_MASK (0xFU)
+
+//
+// Bit masks for the ID_AA64ISAR0_EL1 field values.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_AES_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_FEAT_SHA1_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA256_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_HAVE_CRC32_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_FEAT_LSE_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_RDM_FEAT_RDM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_FEAT_SHA3_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SM3_FEAT_SM3_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SM4_FEAT_SM4_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_DP_FEAT_DOTPROD_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_FHM_FEAT_FHM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIOS_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_FEAT_RNG_MASK (0x1U)
+
+/**
+ Reads the current value of ID_AA64ISAR0_EL1 register.
+
+ Reads and returns the current value of ID_AA64ISAR0_EL1.
+ This function is only available on AARCH64.
+
+ @return The current value of ID_AA64ISAR0_EL1
+**/
+UINT64
+EFIAPI
+ArmReadIdAA64Isar0Reg (
+ VOID
+ );
+
#endif // defined (MDE_CPU_AARCH64)
#if defined (MDE_CPU_RISCV64)
@@ -2902,7 +2970,7 @@ InitializeListHead (
If ListHead is NULL, then ASSERT().
If Entry is NULL, then ASSERT().
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If ListHead was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and prior to insertion the number
of nodes in ListHead, including the ListHead node, is greater than or
@@ -2931,7 +2999,7 @@ InsertHeadList (
If ListHead is NULL, then ASSERT().
If Entry is NULL, then ASSERT().
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If ListHead was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and prior to insertion the number
of nodes in ListHead, including the ListHead node, is greater than or
@@ -2955,11 +3023,11 @@ InsertTailList (
Retrieves the first node of a doubly linked list.
Returns the first node of a doubly linked list. List must have been
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+ initialized with INITIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is empty, then List is returned.
If List is NULL, then ASSERT().
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If List was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
@@ -2981,12 +3049,12 @@ GetFirstNode (
Retrieves the next node of a doubly linked list.
Returns the node of a doubly linked list that follows Node.
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
+ List must have been initialized with INITIALIZE_LIST_HEAD_VARIABLE()
or InitializeListHead(). If List is empty, then List is returned.
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If List was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and List contains more than
PcdMaximumLinkedListLength nodes, then ASSERT().
@@ -3009,12 +3077,12 @@ GetNextNode (
Retrieves the previous node of a doubly linked list.
Returns the node of a doubly linked list that precedes Node.
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
+ List must have been initialized with INITIALIZE_LIST_HEAD_VARIABLE()
or InitializeListHead(). If List is empty, then List is returned.
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If List was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and List contains more than
PcdMaximumLinkedListLength nodes, then ASSERT().
@@ -3040,7 +3108,7 @@ GetPreviousNode (
zero nodes, this function returns TRUE. Otherwise, it returns FALSE.
If ListHead is NULL, then ASSERT().
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If ListHead was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
@@ -3065,11 +3133,11 @@ IsListEmpty (
Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the
nodes in the doubly linked list specified by List. List must have been
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+ initialized with INITIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),
+ If List was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),
then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
@@ -3096,11 +3164,11 @@ IsNull (
Returns TRUE if Node is the last node in the doubly linked list specified by
List. Otherwise, FALSE is returned. List must have been initialized with
- INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+ INITIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+ If List was not initialized with INITIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
@@ -3129,7 +3197,7 @@ IsNodeAtEnd (
Otherwise, the location of the FirstEntry node is swapped with the location
of the SecondEntry node in a doubly linked list. SecondEntry must be in the
same double linked list as FirstEntry and that double linked list must have
- been initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+ been initialized with INITIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
SecondEntry is returned after the nodes are swapped.
If FirstEntry is NULL, then ASSERT().
@@ -3774,7 +3842,7 @@ DivS64x64Remainder (
UINT16
EFIAPI
ReadUnaligned16 (
- IN CONST UINT16 *Buffer
+ IN CONST VOID *Buffer
);
/**
@@ -3795,7 +3863,7 @@ ReadUnaligned16 (
UINT16
EFIAPI
WriteUnaligned16 (
- OUT UINT16 *Buffer,
+ OUT VOID *Buffer,
IN UINT16 Value
);
@@ -3815,7 +3883,7 @@ WriteUnaligned16 (
UINT32
EFIAPI
ReadUnaligned24 (
- IN CONST UINT32 *Buffer
+ IN CONST VOID *Buffer
);
/**
@@ -3836,7 +3904,7 @@ ReadUnaligned24 (
UINT32
EFIAPI
WriteUnaligned24 (
- OUT UINT32 *Buffer,
+ OUT VOID *Buffer,
IN UINT32 Value
);
@@ -3856,7 +3924,7 @@ WriteUnaligned24 (
UINT32
EFIAPI
ReadUnaligned32 (
- IN CONST UINT32 *Buffer
+ IN CONST VOID *Buffer
);
/**
@@ -3877,7 +3945,7 @@ ReadUnaligned32 (
UINT32
EFIAPI
WriteUnaligned32 (
- OUT UINT32 *Buffer,
+ OUT VOID *Buffer,
IN UINT32 Value
);
@@ -3897,7 +3965,7 @@ WriteUnaligned32 (
UINT64
EFIAPI
ReadUnaligned64 (
- IN CONST UINT64 *Buffer
+ IN CONST VOID *Buffer
);
/**
@@ -3918,7 +3986,7 @@ ReadUnaligned64 (
UINT64
EFIAPI
WriteUnaligned64 (
- OUT UINT64 *Buffer,
+ OUT VOID *Buffer,
IN UINT64 Value
);
@@ -4630,6 +4698,101 @@ BitFieldCountOnes64 (
IN UINTN EndBit
);
+/*******************************************************************************
+
+ UUID (Universally Unique IDentifier), as defined in RFC4122
+ (https://datatracker.ietf.org/doc/html/rfc4122#section-4.1), is a 128-bit number
+ used to uniquely identify information in computer systems.
+
+ UUIDs contains 5 fields:
+ - time_low: 32 bits
+ - time_mid: 16 bits
+ - time_hi_and_version: 16 bits
+ - clock_seq_hi_and_reserved: 8 bits
+ - clock_seq_low: 8 bits
+ - node: 8 bits * 6
+
+ Each field encoded with the Most Significant Byte first (known as network byte
+ order, or big-endian).
+
+ GUID (Globally Unique Identifier), on the other hand, is a 128-bit number used
+ in UEFI environments, which is similar to UUID but has a different byte order
+ in memory. See https://uefi.org/specs/UEFI/2.11/Apx_A_GUID_and_Time_Formats.html
+
+ GUID also contains 5 fields:
+ - TimeLow: 32 bits
+ - TimeMid: 16 bits
+ - TimeHiAndVersion: 16 bits
+ - ClockSeqHighAndReserved: 16 bits
+ - ClockSeqLow: 8 bits
+ - Node: 8 bits * 6
+
+ TimeLow, TimeMid, TimeHighAndVersion fields in the EFI are encoded with the Least
+ Significant Byte first (also known as little-endian).
+
+ Example:
+ Consider the same string representation/registry format for MM communication v2:
+ "378daedc-f06b-4446-8314-40ab933c87a3"
+
+ In UUID format, it is represented as:
+ - Data fields:
+ - time_low: 0x37 0x8d 0xae 0xdc (0x378daedc in big-endian)
+ - time_mid: 0xf0 0x6b (0xf06b in big-endian)
+ - time_hi_and_version: 0x44 0x46 (0x4446 in big-endian)
+ - clock_seq_hi_and_reserved: 0x83
+ - clock_seq_low: 0x14
+ - node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
+ - Byte representation in memory:
+ - 37 8d ae dc f0 6b 44 46 83 14 40 ab 93 3c 87 a3
+
+ However, in GUID format, it is represented as:
+ - Data fields:
+ - TimeLow: 0xdc 0xae 0x8d 0x37 (0x378daedc in little-endian)
+ - TimeMid: 0x6b 0xf0 (0xf06b in little-endian)
+ - TimeHiAndVersion: 0x46 0x44 (0x4446 in little-endian)
+ - ClockSeqHighAndReserved: 0x83
+ - ClockSeqLow: 0x14
+ - Node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
+ - Byte representation in memory:
+ - dc ae 8d 37 6b f0 46 44 83 14 40 ab 93 3c 87 a3
+
+*******************************************************************************/
+
+/**
+ This function converts a GUID in UEFI format to a UUID in RFC4122 format.
+
+ The conversion is done by swapping the byte order of the TimeLow, TimeMid, and
+ TimeHiAndVersion fields, while keeping the ClockSeq and Node fields unchanged.
+
+ @param [in] FromGuid GUID in format to be converted to UUID RFC4122 format.
+ @param [out] ToUuid Pointer to a GUID structure that will hold the converted
+ UUID in RFC4122 format.
+**/
+VOID
+EFIAPI
+ConvertGuidToUuid (
+ IN GUID *FromGuid,
+ OUT GUID *ToUuid
+ );
+
+/**
+ This function converts a UUID in RFC4122 format to a GUID in UEFI format.
+
+ The conversion is done by swapping the byte order of the time_low, time_mid, and
+ time_hi_and_version fields, while keeping the ClockSeq and Node fields unchanged.
+ This function is symmetric to ConvertGuidToUuid.
+
+ @param [in] FromUuid UUID in RFC4122 format to be converted to GUID in UEFI format.
+ @param [out] ToGuid Pointer to a GUID structure that will hold the converted
+ GUID in UEFI format.
+**/
+VOID
+EFIAPI
+ConvertUuidToGuid (
+ IN GUID *FromUuid,
+ OUT GUID *ToGuid
+ );
+
//
// Base Library Checksum Functions
//
@@ -4902,6 +5065,23 @@ CalculateCrc32c (
IN UINT32 InitialValue
);
+/**
+ Calculates the CRC16-CCITT-FALSE checksum of the given buffer.
+
+ @param[in] Buffer Pointer to the buffer.
+ @param[in] Length Length of the buffer, in bytes.
+ @param[in] InitialValue Initial value of the CRC.
+
+ @return The CRC16-CCITT-FALSE checksum.
+**/
+UINT16
+EFIAPI
+CalculateCrc16CcittF (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 InitialValue
+ );
+
//
// Base Library CPU Functions
//
@@ -5157,8 +5337,6 @@ SpeculationBarrier (
VOID
);
-#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
-
/**
The TDCALL instruction causes a VM exit to the Intel TDX module. It is
used to call guest-side Intel TDX functions, either local or a TD exit
@@ -5221,7 +5399,17 @@ TdIsEnabled (
VOID
);
-#endif
+/**
+ Probe if running as some kind of SEV guest.
+
+ @return FALSE Not running as a guest under any kind of SEV
+ @return TRUE Running as a guest under any kind of SEV
+**/
+BOOLEAN
+EFIAPI
+SevGuestIsEnabled (
+ VOID
+ );
#if defined (MDE_CPU_X64)
//
@@ -7878,6 +8066,45 @@ AsmVmgExit (
VOID
);
+///
+/// The structure used to supply and return data to and from the SVSM.
+///
+typedef struct {
+ VOID *Caa;
+ UINT64 RaxIn;
+ UINT64 RcxIn;
+ UINT64 RdxIn;
+ UINT64 R8In;
+ UINT64 R9In;
+ UINT64 RaxOut;
+ UINT64 RcxOut;
+ UINT64 RdxOut;
+ UINT64 R8Out;
+ UINT64 R9Out;
+ UINT8 *CallPending;
+} SVSM_CALL_DATA;
+
+/**
+ Executes a VMGEXIT instruction (VMMCALL with a REP prefix) with arguments
+ and return code
+
+ Executes a VMGEXIT instruction placing the specified arguments in the
+ corresponding registers before invocation. Upon return an XCHG is done to
+ atomically clear and retrieve the SVSM call pending value. The returned RAX
+ register value becomes the function return code. This function is intended
+ for use with an SVSM. This function is only available on IA-32 and x64.
+
+ @param[in,out] SvsmCallPending Pointer to the location of the SVSM call data
+
+ @return Value of the RAX register on return
+
+**/
+UINT32
+EFIAPI
+AsmVmgExitSvsm (
+ IN OUT SVSM_CALL_DATA *SvsmCallData
+ );
+
/**
Patch the immediate operand of an IA32 or X64 instruction such that the byte,
word, dword or qword operand is encoded at the end of the instruction's