aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe')
-rw-r--r--roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounter.c269
-rw-r--r--roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf55
-rw-r--r--roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.uni16
-rw-r--r--roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxeExtra.uni14
4 files changed, 354 insertions, 0 deletions
diff --git a/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounter.c b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounter.c
new file mode 100644
index 000000000..f74b0b8a1
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounter.c
@@ -0,0 +1,269 @@
+/** @file
+ Produce the UEFI boot service GetNextMonotonicCount() and runtime service
+ GetNextHighMonotonicCount().
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/MonotonicCounter.h>
+#include <Guid/MtcVendor.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+//
+// The handle to install Monotonic Counter Architctural Protocol
+//
+EFI_HANDLE mMonotonicCounterHandle = NULL;
+
+//
+// The current monotonic counter value
+//
+UINT64 mEfiMtc;
+
+//
+// Event to update the monotonic Counter's high part when low part overflows.
+//
+EFI_EVENT mEfiMtcEvent;
+
+/**
+ Returns a monotonically increasing count for the platform.
+
+ This function returns a 64-bit value that is numerically larger then the last
+ time the function was called.
+ The platform monotonic counter is comprised of two parts: the high 32 bits
+ and the low 32 bits. The low 32-bit value is volatile and is reset to zero on
+ every system reset. It is increased by 1 on every call to GetNextMonotonicCount().
+ The high 32-bit value is nonvolatile and is increased by one on whenever the
+ system resets or the low 32-bit counter overflows.
+
+ @param Count Pointer to returned value.
+
+ @retval EFI_SUCCESS The next monotonic count was returned.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly.
+ @retval EFI_INVALID_PARAMETER Count is NULL.
+ @retval EFI_UNSUPPORTED This function is called at runtime.
+
+**/
+EFI_STATUS
+EFIAPI
+MonotonicCounterDriverGetNextMonotonicCount (
+ OUT UINT64 *Count
+ )
+{
+ EFI_TPL OldTpl;
+
+ //
+ // Cannot be called after ExitBootServices()
+ //
+ if (EfiAtRuntime ()) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Check input parameters
+ //
+ if (Count == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Update the monotonic counter with a lock
+ //
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ *Count = mEfiMtc;
+ mEfiMtc++;
+ gBS->RestoreTPL (OldTpl);
+
+ //
+ // If the low 32-bit counter overflows (MSB bit toggled),
+ // then signal that the high part needs update now.
+ //
+ if ((((UINT32) mEfiMtc) ^ ((UINT32) *Count)) & BIT31) {
+ gBS->SignalEvent (mEfiMtcEvent);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns the next high 32 bits of the platform's monotonic counter.
+
+ The GetNextHighMonotonicCount() function returns the next high 32 bits
+ of the platform's monotonic counter. The platform's monotonic counter is
+ comprised of two 32 bit quantities: the high 32 bits and the low 32 bits.
+ During boot service time the low 32 bit value is volatile: it is reset to
+ zero on every system reset and is increased by 1 on every call to GetNextMonotonicCount().
+ The high 32 bit value is non-volatile and is increased by 1 whenever the system resets,
+ whenever GetNextHighMonotonicCount() is called, or whenever the low 32 bit count
+ (returned by GetNextMonoticCount()) overflows.
+ The GetNextMonotonicCount() function is only available at boot services time.
+ If the operating system wishes to extend the platform monotonic counter to runtime,
+ it may do so by utilizing GetNextHighMonotonicCount(). To do this, before calling
+ ExitBootServices() the operating system would call GetNextMonotonicCount() to obtain
+ the current platform monotonic count. The operating system would then provide an
+ interface that returns the next count by:
+ Adding 1 to the last count.
+ Before the lower 32 bits of the count overflows, call GetNextHighMonotonicCount().
+ This will increase the high 32 bits of the platform's non-volatile portion of the monotonic
+ count by 1.
+
+ This function may only be called at Runtime.
+
+ @param HighCount Pointer to returned value.
+
+ @retval EFI_SUCCESS The next high monotonic count was returned.
+ @retval EFI_INVALID_PARAMETER HighCount is NULL.
+ @retval EFI_DEVICE_ERROR The variable could not be saved due to a hardware failure.
+ @retval EFI_OUT_OF_RESOURCES If variable service reports that not enough storage
+ is available to hold the variable and its data.
+
+**/
+EFI_STATUS
+EFIAPI
+MonotonicCounterDriverGetNextHighMonotonicCount (
+ OUT UINT32 *HighCount
+ )
+{
+ EFI_TPL OldTpl;
+
+ //
+ // Check input parameters
+ //
+ if (HighCount == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!EfiAtRuntime ()) {
+ //
+ // Use a lock if called before ExitBootServices()
+ //
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ *HighCount = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;
+ mEfiMtc = LShiftU64 (*HighCount, 32);
+ gBS->RestoreTPL (OldTpl);
+ } else {
+ *HighCount = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;
+ mEfiMtc = LShiftU64 (*HighCount, 32);
+ }
+ //
+ // Update the NV variable to match the new high part
+ //
+ return EfiSetVariable (
+ MTC_VARIABLE_NAME,
+ &gMtcVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT32),
+ HighCount
+ );
+
+}
+
+/**
+ Monotonic counter event handler. This handler updates the high part of monotonic counter.
+
+ @param Event The event to handle.
+ @param Context The event context.
+
+**/
+VOID
+EFIAPI
+EfiMtcEventHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 HighCount;
+
+ MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);
+}
+
+/**
+ Entry point of monotonic counter driver.
+
+ @param ImageHandle The image handle of this driver.
+ @param SystemTable The pointer of EFI_SYSTEM_TABLE.
+
+ @retval EFI_SUCCESS The initialization is successful.
+
+**/
+EFI_STATUS
+EFIAPI
+MonotonicCounterDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HighCount;
+ UINTN BufferSize;
+
+ //
+ // Make sure the Monotonic Counter Architectural Protocol has not been installed in the system yet.
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMonotonicCounterArchProtocolGuid);
+
+ //
+ // Initialize event to handle low-part overflow
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ EfiMtcEventHandler,
+ NULL,
+ &mEfiMtcEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Read the last high part
+ //
+ BufferSize = sizeof (UINT32);
+ Status = EfiGetVariable (
+ MTC_VARIABLE_NAME,
+ &gMtcVendorGuid,
+ NULL,
+ &BufferSize,
+ &HighCount
+ );
+ if (EFI_ERROR (Status)) {
+ HighCount = 0;
+ }
+ //
+ // Set the current value
+ //
+ mEfiMtc = LShiftU64 (HighCount, 32);
+
+ //
+ // Increment the upper 32 bits for this boot
+ // Continue even if it fails. It will only fail if the variable services are
+ // not functional.
+ //
+ MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);
+
+ //
+ // Fill in the EFI Boot Services and EFI Runtime Services Monotonic Counter Fields
+ //
+ gBS->GetNextMonotonicCount = MonotonicCounterDriverGetNextMonotonicCount;
+ gRT->GetNextHighMonotonicCount = MonotonicCounterDriverGetNextHighMonotonicCount;
+
+ //
+ // Install the Monotonic Counter Architctural Protocol onto a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mMonotonicCounterHandle,
+ &gEfiMonotonicCounterArchProtocolGuid,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
new file mode 100644
index 000000000..f08f17cfb
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# This module produces the UEFI boot service GetNextMonotonicCount() and runtime service GetNextHighMonotonicCount().
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MonotonicCounterRuntimeDxe
+ MODULE_UNI_FILE = MonotonicCounterRuntimeDxe.uni
+ FILE_GUID = AD608272-D07F-4964-801E-7BD3B7888652
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = MonotonicCounterDriverInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ MonotonicCounter.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ DebugLib
+ UefiRuntimeLib
+ UefiDriverEntryPoint
+ BaseLib
+
+[Guids]
+ ## PRODUCES ## Variable:L"MTC"
+ ## CONSUMES ## Variable:L"MTC"
+ gMtcVendorGuid
+
+[Protocols]
+ gEfiMonotonicCounterArchProtocolGuid ## PRODUCES
+
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ MonotonicCounterRuntimeDxeExtra.uni
diff --git a/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.uni b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.uni
new file mode 100644
index 000000000..e00fc13e3
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.uni
@@ -0,0 +1,16 @@
+// /** @file
+// This module produces the UEFI boot service GetNextMonotonicCount() and runtime service GetNextHighMonotonicCount().
+//
+// This module produces the UEFI boot service GetNextMonotonicCount() and runtime service GetNextHighMonotonicCount().
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Produces the UEFI boot service GetNextMonotonicCount() and runtime service GetNextHighMonotonicCount()"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module produces the UEFI boot service GetNextMonotonicCount() and runtime service GetNextHighMonotonicCount()."
+
diff --git a/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxeExtra.uni b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxeExtra.uni
new file mode 100644
index 000000000..0b505cf05
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// MonotonicCounterRuntimeDxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Monotonic Counter DXE Driver"
+
+