diff options
24 files changed, 1212 insertions, 65 deletions
diff --git a/ArmPkg/Include/IndustryStandard/ArmTransferList.h b/ArmPkg/Include/IndustryStandard/ArmTransferList.h index 303384622f..2bc0d80177 100644 --- a/ArmPkg/Include/IndustryStandard/ArmTransferList.h +++ b/ArmPkg/Include/IndustryStandard/ArmTransferList.h @@ -74,6 +74,12 @@ #define TRANSFER_LIST_FL_HAS_CHECKSUM BIT0
/*
+ * Flag values for TPM event log table entry layout XFERLIST_EVLOG->Flags,
+ * see https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfer_list.rst#tpm-event-log-table-entry-layout-xferlist_evlog
+ */
+#define TRANSFER_LIST_EVENTLOG_FL_NEED_TO_REPLAY BIT0 /* Need to replay */
+
+/*
* Operation codes indicating the validity of the Transfer List.
*/
typedef enum {
@@ -137,4 +143,18 @@ typedef struct TransferEntryHeader { UINT32 DataSize;
} TRANSFER_ENTRY_HEADER;
+/*
+ * TPM event log information entry,
+ * see Section 'TPM event log table entry layout (XFERLIST_EVLOG)' in
+ * the Firmware Handoff specification.
+ */
+typedef struct TransferListEventLog {
+ /// See the TRANSFER_LIST_EVENT_LOG_FL_*
+ UINT32 Flags;
+
+ /// TPM event log as much as
+ /// TRNASFER_ENTRY_HEADER->DataSize - sizeof (TRANSFER_LIST_EVENTLOG)->Flags
+ UINT8 EventLog[];
+} TRANSFER_LIST_EVENTLOG;
+
#endif // ARM_TRANSFER_LIST_
diff --git a/ArmPkg/Include/Library/ArmTransferListLib.h b/ArmPkg/Include/Library/ArmTransferListLib.h index fb0c69972e..09ade9f4a1 100644 --- a/ArmPkg/Include/Library/ArmTransferListLib.h +++ b/ArmPkg/Include/Library/ArmTransferListLib.h @@ -19,6 +19,21 @@ #include <Pi/PiHob.h>
/**
+ Get the TransferList from HOB list.
+
+ @param[out] TransferList TransferList
+
+ @retval EFI_SUCCESS TransferList is found.
+ @retval EFI_NOT_FOUND TransferList is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetFromHobList (
+ OUT TRANSFER_LIST_HEADER **TransferList
+ );
+
+/**
Return the first Transfer Entry Node in the Transfer List.
@param [in] TransferListHeader Pointer to the Transfer List Header.
@@ -157,4 +172,26 @@ TransferListFindEntry ( IN UINT16 TagId
);
+/**
+ Get TPM event log from TransferList
+
+ @param [in] TransferListHeader Pointer to the Transfer List Header
+ @param [out] EventLog Pointer to Eventlog in TransferList
+ @param [out] EventLogSize Size of Event log
+ @param [out] EventLogFlags Flags for Event log
+
+ @return EFI_SUCCESS
+ @return EFI_NOT_FOUND No Event log in TransferListHeader
+ @return EFI_INVALID_PARAMETER Invalid parameters
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetEventLog (
+ IN TRANSFER_LIST_HEADER *TransferListHeader,
+ OUT VOID **EventLog,
+ OUT UINTN *EventLogSize,
+ OUT UINT32 *EventLogFlags OPTIONAL
+ );
+
#endif // ARM_TRANSFER_LIST_LIB_
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c index af8170e67f..06d66292b4 100644 --- a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c @@ -13,6 +13,45 @@ #include <Library/ArmTransferListLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+/**
+ Get the TransferList from HOB list.
+
+ @param[out] TransferList TransferList
+
+ @retval EFI_SUCCESS TransferList is found.
+ @retval EFI_NOT_FOUND TransferList is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetFromHobList (
+ OUT TRANSFER_LIST_HEADER **TransferList
+ )
+{
+ VOID *HobList;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINTN *GuidHobData;
+
+ *TransferList = NULL;
+
+ HobList = GetHobList ();
+ if (HobList == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob = GetNextGuidHob (&gArmTransferListHobGuid, HobList);
+ if (GuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHobData = GET_GUID_HOB_DATA (GuidHob);
+
+ *TransferList = (TRANSFER_LIST_HEADER *)(*GuidHobData);
+
+ return EFI_SUCCESS;
+}
/**
This function verifies the checksum of the Transfer List.
@@ -275,6 +314,56 @@ TransferListFindEntry ( }
/**
+ Get TPM event log from TransferList
+
+ @param [in] TransferListHeader Pointer to the Transfer List Header
+ @param [out] EventLog Pointer to Eventlog in TransferList
+ @param [out] EventLogSize Size of Event log
+ @param [out] EventLogFlags Flags for Event log
+
+ @return EFI_SUCCESS
+ @return EFI_NOT_FOUND No Event log in TransferListHeader
+ @return EFI_INVALID_PARAMETER Invalid parameters
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetEventLog (
+ IN TRANSFER_LIST_HEADER *TransferListHeader,
+ OUT VOID **EventLog,
+ OUT UINTN *EventLogSize,
+ OUT UINT32 *EventLogFlags OPTIONAL
+ )
+{
+ TRANSFER_ENTRY_HEADER *Entry;
+ TRANSFER_LIST_EVENTLOG *EntryData;
+
+ if ((TransferListHeader == NULL) || (EventLog == NULL) || (EventLogSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *EventLog = NULL;
+ *EventLogSize = 0;
+
+ Entry = TransferListFindFirstEntry (TransferListHeader, TRANSFER_ENTRY_TAG_ID_TPM_EVENT_LOG);
+ if ((Entry == NULL) || (Entry->DataSize == 0) ||
+ ((Entry->DataSize - OFFSET_OF (TRANSFER_LIST_EVENTLOG, EventLog)) == 0))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ EntryData = TransferListGetEntryData (Entry);
+ if (EventLogFlags != NULL) {
+ *EventLogFlags = EntryData->Flags;
+ }
+
+ *EventLogSize = Entry->DataSize - OFFSET_OF (TRANSFER_LIST_EVENTLOG, EventLog);
+ *EventLog = (VOID *)&EntryData->EventLog;
+
+ return EFI_SUCCESS;
+}
+
+/**
Dump the transfer list to the debug output.
@param [in] TransferListHeader Pointer to the Transfer List Header
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf index b1eeb8a1f7..5ffb1a4d9c 100644 --- a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf @@ -25,3 +25,6 @@ [LibraryClasses]
BaseLib
+
+[Guids]
+ gArmTransferListHobGuid
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index d791351f6b..2dc36d69d6 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -72,6 +72,7 @@ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
!include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 1e239bbbf7..c8e8ab2b05 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -103,6 +103,11 @@ !endif
ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogDxeLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
[LibraryClasses.AARCH64]
ArmPlatformLib|ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf
@@ -115,6 +120,12 @@ ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorPeiLib/ArmVirtMonitorPeiLib.inf
FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
[LibraryClasses.AARCH64.PEIM]
ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
@@ -335,6 +346,23 @@ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!endif
+[LibraryClasses.common.SEC]
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+
+[LibraryClasses.common.PEI_CORE]
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCoreLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogRtLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -350,6 +378,10 @@ ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
ArmPkg/Drivers/CpuPei/CpuPei.inf
+!if $(DEBUG_TO_MEM)
+ OvmfPkg/MemDebugLogPei/MemDebugLogPei.inf
+!endif
+
!if $(TPM2_ENABLE) == TRUE
MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
<LibraryClasses>
diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf index ac2040acff..1e45d51729 100644 --- a/ArmVirtPkg/ArmVirtQemu.fdf +++ b/ArmVirtPkg/ArmVirtQemu.fdf @@ -111,6 +111,10 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/CpuPei/CpuPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+!if $(DEBUG_TO_MEM)
+ INF OvmfPkg/MemDebugLogPei/MemDebugLogPei.inf
+!endif
+
!if $(TPM2_ENABLE) == TRUE
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c index 83d52e98f5..18222aaebc 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c @@ -24,6 +24,7 @@ #include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/MemDebugLogLib.h>
#include "Write.h"
@@ -117,6 +118,13 @@ DebugPrintMarker ( }
//
+ // Send string to Memory Debug Log if enabled
+ //
+ if (MemDebugLogEnabled ()) {
+ MemDebugLogWrite ((CHAR8 *)Buffer, AsciiStrLen (Buffer));
+ }
+
+ //
// Send the print string to a Serial Port
//
DebugLibFdtPL011UartWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
@@ -213,6 +221,13 @@ DebugAssert ( AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] %a(%d): %a\n", gEfiCallerBaseName, FileName, LineNumber, Description);
//
+ // Send string to Memory Debug Log if enabled
+ //
+ if (MemDebugLogEnabled ()) {
+ MemDebugLogWrite ((CHAR8 *)Buffer, AsciiStrLen (Buffer));
+ }
+
+ //
// Send the print string to the Console Output device
//
DebugLibFdtPL011UartWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf index f35a0913f0..6b3b3316a2 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf @@ -40,6 +40,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress # Flash.c
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf index a5f4c2d80a..568fc3e6b2 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf @@ -34,6 +34,7 @@ ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
@@ -43,6 +44,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf index 84e9dbae22..1ae3f9993a 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf @@ -35,6 +35,7 @@ ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
@@ -44,6 +45,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c index cbdab6c22f..05e32daf1c 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c @@ -12,9 +12,6 @@ #include <Library/QemuFwCfgSimpleParserLib.h>
#include <Library/MemDebugLogLib.h>
-EFI_PHYSICAL_ADDRESS mMemDebugLogBufAddr;
-BOOLEAN mMemDebugLogBufAddrInit;
-
EFI_STATUS
EFIAPI
MemDebugLogWrite (
@@ -22,23 +19,21 @@ MemDebugLogWrite ( IN UINTN Length
)
{
- EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemDebugLogBufAddr;
+ EFI_STATUS Status;
- if (!mMemDebugLogBufAddrInit) {
- //
- // Obtain the Memory Debug Log buffer addr from HOB
- // NOTE: This is expected to fail until the HOB is created.
- //
- Status = MemDebugLogAddrFromHOB (&mMemDebugLogBufAddr);
- if (EFI_ERROR (Status)) {
- mMemDebugLogBufAddr = 0;
- } else {
- mMemDebugLogBufAddrInit = TRUE;
- }
+ //
+ // Obtain the Memory Debug Log buffer addr from HOB
+ // NOTE: This is expected to fail until the HOB is created.
+ //
+ Status = MemDebugLogAddrFromHOB (&MemDebugLogBufAddr);
+
+ if (EFI_ERROR (Status)) {
+ MemDebugLogBufAddr = 0;
}
- if (mMemDebugLogBufAddr) {
- Status = MemDebugLogWriteBuffer (mMemDebugLogBufAddr, Buffer, Length);
+ if (MemDebugLogBufAddr != 0) {
+ Status = MemDebugLogWriteBuffer (MemDebugLogBufAddr, Buffer, Length);
} else {
//
// HOB has not yet been created, so
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c index 1e95d65aaa..c8de40d5c1 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c @@ -11,9 +11,6 @@ #include <Library/PeiServicesLib.h>
#include <Library/MemDebugLogLib.h>
-EFI_PHYSICAL_ADDRESS mMemDebugLogBufAddr;
-BOOLEAN mMemDebugLogBufAddrInit;
-
EFI_STATUS
EFIAPI
MemDebugLogWrite (
@@ -21,23 +18,20 @@ MemDebugLogWrite ( IN UINTN Length
)
{
- EFI_STATUS Status;
-
- if (!mMemDebugLogBufAddrInit) {
- //
- // Obtain the Memory Debug Log buffer addr from HOB
- // NOTE: This is expected to fail until the HOB is created.
- //
- Status = MemDebugLogAddrFromHOB (&mMemDebugLogBufAddr);
- if (EFI_ERROR (Status)) {
- mMemDebugLogBufAddr = 0;
- } else {
- mMemDebugLogBufAddrInit = TRUE;
- }
+ EFI_PHYSICAL_ADDRESS MemDebugLogBufAddr;
+ EFI_STATUS Status;
+
+ //
+ // Obtain the Memory Debug Log buffer addr from HOB
+ // NOTE: This is expected to fail until the HOB is created.
+ //
+ Status = MemDebugLogAddrFromHOB (&MemDebugLogBufAddr);
+ if (EFI_ERROR (Status)) {
+ MemDebugLogBufAddr = 0;
}
- if (mMemDebugLogBufAddr) {
- Status = MemDebugLogWriteBuffer (mMemDebugLogBufAddr, Buffer, Length);
+ if (MemDebugLogBufAddr != 0) {
+ Status = MemDebugLogWriteBuffer (MemDebugLogBufAddr, Buffer, Length);
} else {
//
// HOB has not yet been created, so
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf index 18f06e45b3..b6b407c891 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf @@ -29,11 +29,6 @@ [LibraryClasses]
SynchronizationLib
PcdLib
-
-[LibraryClasses.Ia32]
- QemuFwCfgSimpleParserLib
-
-[LibraryClasses.X64]
QemuFwCfgSimpleParserLib
[Guids]
diff --git a/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c new file mode 100644 index 0000000000..037174dc6a --- /dev/null +++ b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c @@ -0,0 +1,643 @@ +/** @file
+ This driver init default Secure Boot variables
+
+ Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
+ Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2021, Semihalf All rights reserved.<BR>
+ Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+ Copyright (C) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <UefiSecureBoot.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <Guid/ImageAuthentication.h>
+#include <Library/SecureBootVariableLib.h>
+#include <Library/SecureBootVariableProvisionLib.h>
+
+/**
+ Set PKDefault Variable.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+
+ @retval EFI_SUCCESS PKDefault is set successfully.
+
+**/
+EFI_STATUS
+SetPkDefault (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Attr;
+ UINTN DataSize;
+ EFI_SIGNATURE_LIST *PkCert;
+ EFI_SIGNATURE_DATA *PkCertData;
+
+ PkCert = NULL;
+
+ //
+ // Allocate space for PK certificate list and initialize it.
+ // Create PK database entry with SignatureHeaderSize equals 0.
+ //
+ PkCert = (EFI_SIGNATURE_LIST *)AllocateZeroPool (
+ sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize
+ );
+ if (PkCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ PkCert->SignatureListSize = (UINT32)(sizeof (EFI_SIGNATURE_LIST)
+ + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize);
+ PkCert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ PkCert->SignatureHeaderSize = 0;
+ CopyGuid (&PkCert->SignatureType, &gEfiCertX509Guid);
+ PkCertData = (EFI_SIGNATURE_DATA *)((UINTN)PkCert
+ + sizeof (EFI_SIGNATURE_LIST)
+ + PkCert->SignatureHeaderSize);
+ CopyGuid (&PkCertData->SignatureOwner, &gEfiGlobalVariableGuid);
+ //
+ // Fill the PK database with PKpub data from X509 certificate file.
+ //
+ CopyMem (&(PkCertData->SignatureData[0]), X509Data, X509DataSize);
+
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ DataSize = PkCert->SignatureListSize;
+
+ Status = gRT->SetVariable (
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ DataSize,
+ PkCert
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (PkCert != NULL) {
+ FreePool (PkCert);
+ }
+
+ return Status;
+}
+
+/**
+ Set KDKDefault Variable.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+
+ @retval EFI_SUCCESS KEKDefault is set successfully.
+
+**/
+EFI_STATUS
+SetKekDefault (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_DATA *KEKSigData;
+ EFI_SIGNATURE_LIST *KekSigList;
+ UINTN DataSize;
+ UINTN KekSigListSize;
+ UINT32 Attr;
+
+ KekSigList = NULL;
+ KekSigListSize = 0;
+ DataSize = 0;
+ KEKSigData = NULL;
+
+ KekSigListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+ KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
+ if (KekSigList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ KekSigList->SignatureListSize = (UINT32)KekSigListSize;
+ KekSigList->SignatureHeaderSize = 0;
+ KekSigList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&KekSigList->SignatureType, &gEfiCertX509Guid);
+
+ KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&KEKSigData->SignatureOwner, &gEfiGlobalVariableGuid);
+ CopyMem (KEKSigData->SignatureData, X509Data, X509DataSize);
+
+ //
+ // Check if KEK been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new kek to original variable
+ //
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Status = gRT->GetVariable (
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot get the value of KEK: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ KekSigListSize,
+ KekSigList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (KekSigList != NULL) {
+ FreePool (KekSigList);
+ }
+
+ return Status;
+}
+
+/**
+ Checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
+
+ @param[in] Data Data.
+ @param[in] DataSize Data size.
+
+ @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format.
+ @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.
+
+**/
+BOOLEAN
+IsAuthentication2Format (
+ IN UINT8 *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_VARIABLE_AUTHENTICATION_2 *Auth2;
+ BOOLEAN IsAuth2Format;
+
+ IsAuth2Format = FALSE;
+
+ Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;
+ if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
+ goto ON_EXIT;
+ }
+
+ if (CompareGuid (&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) {
+ IsAuth2Format = TRUE;
+ }
+
+ON_EXIT:
+
+ return IsAuth2Format;
+}
+
+/**
+ Set signature database with the data of EFI_VARIABLE_AUTHENTICATION_2 format.
+
+ @param[in] AuthData AUTHENTICATION_2 data.
+ @param[in] AuthDataSize AUTHENTICATION_2 data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+
+ @retval EFI_SUCCESS New signature is set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported command.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+SetAuthentication2ToSigDb (
+ IN UINT8 *AuthData,
+ IN UINTN AuthDataSize,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT32 Attr;
+ UINT8 *Data;
+
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ //
+ // Check if SigDB variable has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot get the value of signature database: %r\n", __func__, Status));
+ return Status;
+ }
+
+ //
+ // Ignore AUTHENTICATION_2 region. Only the actual certificate is needed.
+ //
+ DataSize = AuthDataSize - ((EFI_VARIABLE_AUTHENTICATION_2 *)AuthData)->AuthInfo.Hdr.dwLength - sizeof (EFI_TIME);
+ Data = AuthData + (AuthDataSize - DataSize);
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ DataSize,
+ Data
+ );
+
+ return Status;
+}
+
+/**
+
+ Set signature database with the data of X509 format.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+ @param[in] SignatureOwnerGuid Guid of the signature owner.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+SetX509ToSigDb (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *SignatureOwnerGuid
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigDBCert;
+ EFI_SIGNATURE_DATA *SigDBCertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDBSize;
+ UINT32 Attr;
+
+ SigDBSize = 0;
+ DataSize = 0;
+ SigDBCert = NULL;
+ SigDBCertData = NULL;
+ Data = NULL;
+
+ SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+ Data = AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ SigDBCert = (EFI_SIGNATURE_LIST *)Data;
+ SigDBCert->SignatureListSize = (UINT32)SigDBSize;
+ SigDBCert->SignatureHeaderSize = 0;
+ SigDBCert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&SigDBCert->SignatureType, &gEfiCertX509Guid);
+
+ SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&SigDBCertData->SignatureOwner, SignatureOwnerGuid);
+ CopyMem ((UINT8 *)(SigDBCertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot set signature database: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ return Status;
+}
+
+/**
+
+ Set signature database.
+
+ @param[in] Data Data.
+ @param[in] DataSize Data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+ @param[in] SignatureOwnerGuid Guid of the signature owner.
+
+ @retval EFI_SUCCESS Signature is set successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+SetSignatureDatabase (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *SignatureOwnerGuid
+ )
+{
+ if (IsAuthentication2Format (Data, DataSize)) {
+ return SetAuthentication2ToSigDb (Data, DataSize, VariableName);
+ } else {
+ return SetX509ToSigDb (Data, DataSize, VariableName, SignatureOwnerGuid);
+ }
+}
+
+/** Initializes PKDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitPkDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+
+ //
+ // Enroll default PK.
+ //
+ Status = GetSectionFromFv (
+ &gDefaultPKFileGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetPkDefault (Data, DataSize);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes KEKDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitKekDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultKEKFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetKekDefault (Data, DataSize);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes dbDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitDbDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ Status = GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultdbFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetSignatureDatabase (Data, DataSize, EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes dbxDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitDbxDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultdbxFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetSignatureDatabase (Data, DataSize, EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes default SecureBoot certificates with data from FFS section.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+**/
+EFI_STATUS
+EFIAPI
+SecureBootDefaultKeysInitEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = InitPkDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitKekDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitDbDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize dbDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitDbxDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize dbxDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf new file mode 100644 index 0000000000..0127841733 --- /dev/null +++ b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf @@ -0,0 +1,49 @@ +## @file
+# Initializes Secure Boot default keys
+#
+# Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2021, Semihalf All rights reserved.<BR>
+# Copyright (C) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = SecureBootDefaultKeysInit
+ FILE_GUID = 384D1860-7306-11F0-B8B4-F53A5CB787AC
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecureBootDefaultKeysInitEntry
+
+[Sources]
+ SecureBootDefaultKeysInit.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DxeServicesLib
+ SecureBootVariableLib
+ SecureBootVariableProvisionLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gDefaultdbFileGuid
+ gDefaultdbxFileGuid
+ gDefaultKEKFileGuid
+ gDefaultPKFileGuid
+ gEfiCertPkcs7Guid
+ gEfiCertX509Guid
+ gEfiCustomModeEnableGuid
+ gEfiImageSecurityDatabaseGuid
+ gEfiSecureBootEnableDisableGuid
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c index 54b5d33613..3da71aa51b 100644 --- a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c @@ -1,6 +1,7 @@ /** @file
- Copyright (c) 2011, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2011-2014, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2014-2020, Linaro Limited. All rights reserved.<BR>
Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -45,6 +46,12 @@ CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = { NULL
};
+CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gOvmfTpmDiscoveredPpiGuid,
+ NULL
+};
+
/*
Install PEI memory.
@@ -89,6 +96,126 @@ FindInstallPeiMemory ( ASSERT_EFI_ERROR (PeiServicesInstallPeiMemory (PeiMemoryBase, PEI_MEMORY_SIZE));
}
+/**
+ Set up TPM resources from FDT.
+
+ @param FdtBase Fdt base address
+
+**/
+STATIC
+VOID
+SetupTPMResources (
+ VOID *FdtBase
+ )
+{
+ INT32 Node, Prev;
+ INT32 Parent, Depth;
+ CONST CHAR8 *Compatible;
+ CONST CHAR8 *CompItem;
+ INT32 Len;
+ INT32 RangesLen;
+ CONST UINT8 *RegProp;
+ CONST UINT32 *RangesProp;
+ UINT64 TpmBase;
+ UINT64 TpmBaseSize;
+
+ //
+ // Set Parent to suppress incorrect compiler/analyzer warnings.
+ //
+ Parent = 0;
+
+ for (Prev = Depth = 0; ; Prev = Node) {
+ Node = FdtNextNode (FdtBase, Prev, &Depth);
+ if (Node < 0) {
+ break;
+ }
+
+ if (Depth == 1) {
+ Parent = Node;
+ }
+
+ Compatible = FdtGetProp (FdtBase, Node, "compatible", &Len);
+
+ //
+ // Iterate over the NULL-separated items in the compatible string
+ //
+ for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
+ CompItem += 1 + AsciiStrLen (CompItem))
+ {
+ if (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0) {
+ RegProp = FdtGetProp (FdtBase, Node, "reg", &Len);
+ ASSERT (Len == 8 || Len == 16);
+ if (Len == 8) {
+ TpmBase = Fdt32ToCpu (*(UINT32 *)RegProp);
+ TpmBaseSize = Fdt32ToCpu (*(UINT32 *)((UINT8 *)RegProp + 4));
+ } else if (Len == 16) {
+ TpmBase = Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RegProp));
+ TpmBaseSize = Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)((UINT8 *)RegProp + 8)));
+ }
+
+ if (Depth > 1) {
+ //
+ // QEMU/mach-virt may put the TPM on the platform bus, in which case
+ // we have to take its 'ranges' property into account to translate the
+ // MMIO address. This consists of a <child base, parent base, size>
+ // tuple, where the child base and the size use the same number of
+ // cells as the 'reg' property above, and the parent base uses 2 cells
+ //
+ RangesProp = FdtGetProp (FdtBase, Parent, "ranges", &RangesLen);
+ ASSERT (RangesProp != NULL);
+
+ //
+ // a plain 'ranges' attribute without a value implies a 1:1 mapping
+ //
+ if (RangesLen != 0) {
+ //
+ // assume a single translated range with 2 cells for the parent base
+ //
+ if (RangesLen != Len + 2 * sizeof (UINT32)) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: 'ranges' property has unexpected size %d\n",
+ __func__,
+ RangesLen
+ ));
+ break;
+ }
+
+ if (Len == 8) {
+ TpmBase -= Fdt32ToCpu (RangesProp[0]);
+ } else {
+ TpmBase -= Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
+ }
+
+ //
+ // advance RangesProp to the parent bus address
+ //
+ RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
+ TpmBase += Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (TpmBase) {
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ TpmBase,
+ ALIGN_VALUE (TpmBaseSize, EFI_PAGE_SIZE)
+ );
+
+ ASSERT_EFI_ERROR ((EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase));
+ PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
+ }
+}
+
/*
Entry point of this module.
@@ -125,6 +252,7 @@ InitializePlatformPeim ( MemoryInitialization (SecData->FdtPointer);
CpuInitialization (SecData->FdtPointer);
PlatformInitialization (SecData->FdtPointer);
+ SetupTPMResources (SecData->FdtPointer);
//
// Install PEI memory
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf index 9be96dd3de..6ca005bec9 100644 --- a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf @@ -25,17 +25,24 @@ MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
OvmfPkg/OvmfPkg.dec
+ SecurityPkg/SecurityPkg.dec
[LibraryClasses]
PeimEntryPoint
DebugLib
+ FdtLib
HobLib
+ PcdLib
PeiServicesLib
PlatformSecLib
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
+
[Ppis]
gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
gEfiSecHobDataPpiGuid # ALWAYS_CONSUMED
+ gOvmfTpmDiscoveredPpiGuid # SOMETIMES_PRODUCES
[Depex]
TRUE
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc index bc4935ec2b..c23130a72d 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc @@ -193,13 +193,14 @@ [PcdsFixedAtBuild.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
-!if $(NETWORK_TLS_ENABLE) == TRUE
+!if $(NETWORK_TLS_ENABLE) == TRUE || $(SECURE_BOOT_ENABLE) == TRUE
#
# The cumulative and individual VOLATILE variable size limits should be set
# high enough for accommodating several and/or large CA certificates.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"2.7"
@@ -290,6 +291,8 @@ [LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
!if $(TPM2_ENABLE) == TRUE
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
!else
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!endif
@@ -317,6 +320,24 @@ <LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
}
+!if $(TPM2_ENABLE) == TRUE
+ OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+ SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+ <LibraryClasses>
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf
+ NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+ }
+ SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf {
+ <LibraryClasses>
+ TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
+ }
+!endif
!else
UefiCpuPkg/SecCore/SecCoreNative.inf {
<LibraryClasses>
@@ -370,7 +391,7 @@ !endif
}
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
- OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+ OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf
!else
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
!endif
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf index 3470b18a2e..1f37eb6894 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf @@ -89,6 +89,24 @@ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf !endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+ INF OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf
+
+ FILE FREEFORM = 85254ea7-4759-4fc4-82d4-5eed5fb0a4a0 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/PK/PK.cer
+ }
+
+ FILE FREEFORM = 6f64916e-9f7a-4c35-b952-cd041efb05a3 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/KEK/MicCorKEKCA2011_2011-06-24.crt
+ }
+
+ FILE FREEFORM = c491d352-7623-4843-accc-2791a7574421 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/db/MicWinProPCA2011_2011-10-19.crt
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/db/MicCorUEFCA2011_2011-06-27.crt
+ }
+
+ FILE FREEFORM = 5740766a-718e-4dc0-9935-c36f7d3f884f {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/dbx/dbxupdate_x64.bin
+ }
!endif
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
@@ -212,6 +230,16 @@ INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
#
+# TPM2 support
+#
+!if $(TPM2_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+#
# TianoCore logo (splash screen)
#
INF MdeModulePkg/Logo/LogoDxe.inf
diff --git a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf index 51078c9813..0355df9609 100644 --- a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf +++ b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf @@ -52,3 +52,6 @@ [Depex.ARM, Depex.AARCH64]
gOvmfTpmDiscoveredPpiGuid
+
+[Depex.RISCV64]
+ gOvmfTpmDiscoveredPpiGuid
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c index 5ec80aa637..c6a9804834 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c @@ -542,8 +542,19 @@ OneOfStatementToAttributeValues ( }
if (Option->Text != 0) {
- Values->ValueArray[Index].ValueName = HiiGetRedfishAsciiString (HiiHandle, SchemaName, Option->Text);
Values->ValueArray[Index].ValueDisplayName = HiiGetEnglishAsciiString (HiiHandle, Option->Text);
+ Values->ValueArray[Index].ValueName = HiiGetRedfishAsciiString (HiiHandle, SchemaName, Option->Text);
+ if (Values->ValueArray[Index].ValueName == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ Values->ValueArray[Index].ValueName =
+ AllocateCopyPool (AsciiStrSize (Values->ValueArray[Index].ValueDisplayName), (VOID *)Values->ValueArray[Index].ValueDisplayName);
+ if (Values->ValueArray[Index].ValueName == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ }
+ }
}
Index += 1;
@@ -1309,8 +1320,16 @@ HiiValueToRedfishValue ( RedfishValue->Value.Buffer = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringId);
if (RedfishValue->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- break;
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ RedfishValue->Value.Buffer = HiiGetEnglishAsciiString (HiiHandle, StringId);
+ if (RedfishValue->Value.Buffer == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
}
RedfishValue->Type = RedfishValueTypeString;
@@ -1399,6 +1418,18 @@ HiiValueToRedfishValue ( }
RedfishValue->Value.StringArray[Index] = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringIdArray[Index]);
+ if (RedfishValue->Value.StringArray[Index] == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ RedfishValue->Value.StringArray[Index] = HiiGetEnglishAsciiString (HiiHandle, StringIdArray[Index]);
+ if (RedfishValue->Value.StringArray[Index] == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
ASSERT (RedfishValue->Value.StringArray[Index] != NULL);
}
@@ -1418,6 +1449,7 @@ HiiValueToRedfishValue ( RedfishValue->Value.Buffer = HiiGetRedfishAsciiString (HiiHandle, FullSchema, HiiStatement->ExtraData.TextTwo);
if (RedfishValue->Value.Buffer == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
//
// No x-UEFI-redfish string defined. Try to get string in English.
//
diff --git a/SecurityPkg/FvReportPei/FvReportPei.c b/SecurityPkg/FvReportPei/FvReportPei.c index 50773db056..6c92e7379d 100644 --- a/SecurityPkg/FvReportPei/FvReportPei.c +++ b/SecurityPkg/FvReportPei/FvReportPei.c @@ -343,17 +343,38 @@ GetHashInfo ( }
/**
- Verify and report pre-hashed FVs.
+ Verifies and reports pre-hashed Firmware Volumes (FVs).
- Doing this must be at post-memory to make sure there's enough memory to hold
- all FVs to be verified. This is necessary for mitigating TOCTOU issue.
+ This function should be called after memory initialization (post-memory phase)
+ to ensure sufficient memory is available to hold all FVs for verification.
- This function will never return if the verification is failed.
+ Verifying FVs at this stage is critical to mitigate Time-of-Check to Time-of-Use (TOCTOU) vulnerabilities.
+
+ FV Verification Step:
+
+ This function relies upon an instance of gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid being installed. If
+ an instance of the PPI is not found, EFI_NOT_FOUND is returned.
+
+ If the gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid PPI instance does not have valid hash information for the
+ current boot mode (hash info is NULL), verification is treated as successful.
+
+ FV Reporting Step:
+
+ If FV verification is successful, the function reports the FVs to PEI and/or DXE core for further processing by:
+
+ 1. Installing a FV HOB.
+ 2. Installing a FV Info PPI.
+ 3. Reporting a status code with the value from PcdStatusCodeFvVerificationPass to indicate that FV verification
+ passed.
+
+ If FV verification fails, the function reports a status code with the value from PcdStatusCodeFvVerificationFail
+ and returns a failure status code.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] BootMode Current boot mode.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND No valid gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid PPI instance found.
**/
STATIC
EFI_STATUS
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c index 080e229c40..bb07200754 100644 --- a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c +++ b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c @@ -8,6 +8,7 @@ **/
#include <Uefi.h>
+#include <Guid/RiscVSecHobData.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
@@ -16,9 +17,12 @@ #include <Pi/PiHob.h>
#include <Library/HobLib.h>
#include <Library/FdtLib.h>
+#include <Library/TimerLib.h>
STATIC UINT64 mTimeBase;
+#define GET_TIME_BASE() (mTimeBase ?: GetPerformanceCounterProperties(NULL, NULL))
+
/**
Stalls the CPU for at least the given number of ticks.
@@ -63,7 +67,7 @@ MicroSecondDelay ( DivU64x32 (
MultU64x32 (
MicroSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000u
)
@@ -91,7 +95,7 @@ NanoSecondDelay ( DivU64x32 (
MultU64x32 (
NanoSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000000u
)
@@ -150,6 +154,12 @@ GetPerformanceCounterProperties ( OUT UINT64 *EndValue OPTIONAL
)
{
+ VOID *Hob;
+ RISCV_SEC_HANDOFF_DATA *SecData;
+ CONST EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+ UINT64 TimeBase;
+ CONST VOID *FdtBase;
+
if (StartValue != NULL) {
*StartValue = 0;
}
@@ -165,20 +175,27 @@ GetPerformanceCounterProperties ( //
// Locate the FDT HOB and validate header
//
- CONST EFI_HOB_GUID_TYPE *Hob = GetFirstGuidHob (&gFdtHobGuid);
-
- ASSERT (Hob != NULL);
-
- CONST VOID *DeviceTreeBase =
- (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ Hob = GetFirstGuidHob (&gFdtHobGuid);
+ if (Hob) {
+ FdtBase = (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ } else {
+ //
+ // Get the FDT address from the SEC HOB
+ //
+ Hob = GetFirstGuidHob (&SecHobDataGuid);
+ ASSERT (Hob != NULL);
+ SecData = (RISCV_SEC_HANDOFF_DATA *)GET_GUID_HOB_DATA (Hob);
+ FdtBase = (CONST VOID *)SecData->FdtPointer;
+ }
- ASSERT (FdtCheckHeader (DeviceTreeBase) == 0);
+ ASSERT (FdtBase != NULL);
+ ASSERT (FdtCheckHeader ((VOID *)(UINTN)FdtBase) == 0);
//
// /cpus node
//
INT32 Node = FdtSubnodeOffsetNameLen (
- DeviceTreeBase,
+ FdtBase,
0,
"cpus",
sizeof ("cpus") - 1
@@ -191,15 +208,23 @@ GetPerformanceCounterProperties ( //
INT32 Len;
CONST FDT_PROPERTY *Prop =
- FdtGetProperty (DeviceTreeBase, Node, "timebase-frequency", &Len);
+ FdtGetProperty (FdtBase, Node, "timebase-frequency", &Len);
ASSERT (Prop != NULL && Len == sizeof (UINT32));
//
// Device-tree cells are big-endian
//
- mTimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
- return mTimeBase;
+ TimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
+ ASSERT (TimeBase != 0);
+
+ //
+ // Save the time base for later use. Note that the mTimeBase maybe zero if
+ // this library is stored in read-only memory.
+ //
+ mTimeBase = TimeBase;
+
+ return TimeBase;
}
/**
@@ -227,13 +252,13 @@ GetTimeInNanoSecond ( // Time = --------- x 1,000,000,000
// Frequency
//
- NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, mTimeBase, &Remainder), 1000000000u);
+ NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, GET_TIME_BASE (), &Remainder), 1000000000u);
//
// Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
// will not overflow 64-bit.
//
- NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), mTimeBase);
+ NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), GET_TIME_BASE ());
return NanoSeconds;
}
|