From e70d34ca2afbd75f2eb11a09b94c3865087d96de Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Fri, 6 Jul 2007 09:15:13 +0000 Subject: [PATCH 1/1] Add MonotonicCounter driver, which produces MonotonicCounter arch protocols git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3115 6f19259b-4bc3-4df7-8a09-765794883524 --- .../MonotonicCounterDxe/MonotonicCounter.c | 299 ++++++++++++++++++ .../MonotonicCounterDxe/MonotonicCounter.h | 54 ++++ .../MonotonicCounterDxe/MonotonicCounter.inf | 97 ++++++ .../MonotonicCounterDxe/MonotonicCounter.msa | 65 ++++ 4 files changed, 515 insertions(+) create mode 100644 MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c create mode 100644 MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h create mode 100644 MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf create mode 100644 MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c new file mode 100644 index 0000000000..31efab323a --- /dev/null +++ b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c @@ -0,0 +1,299 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MonotonicCounter.c + +Abstract: + + Produced the Monotonic Counter Services as defined in the DXE CIS + +Revision History: + +--*/ + +#include "MonotonicCounter.h" + +// +// The Monotonic Counter Handle +// +EFI_HANDLE mMonotonicCounterHandle = NULL; + +// +// The current Monotonic count value +// +UINT64 mEfiMtc; + +// +// Event to use to update the Mtc's high part when wrapping +// +EFI_EVENT mEfiMtcEvent; + +// +// EfiMtcName - Variable name of the MTC value +// +CHAR16 *mEfiMtcName = (CHAR16 *) L"MTC"; + +// +// EfiMtcGuid - Guid of the MTC value +// +EFI_GUID mEfiMtcGuid = { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } }; + +// +// Worker functions +// +STATIC +EFI_STATUS +EFIAPI +MonotonicCounterDriverGetNextMonotonicCount ( + OUT UINT64 *Count + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EFI_TPL OldTpl; + + // + // Can not 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 MSB bit of the low part toggled, then signal that the high + // part needs updated now + // + if ((((UINT32) mEfiMtc) ^ ((UINT32) *Count)) & 0x80000000) { + 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 + 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[out] HighCount Pointer to returned value. + + @retval EFI_INVALID_PARAMETER If HighCount is NULL. + @retval EFI_SUCCESS Operation is successful. + @retval EFI_OUT_OF_RESOURCES If variable service reports that not enough storage + is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved due to a hardware failure. + +**/ +STATIC +EFI_STATUS +EFIAPI +MonotonicCounterDriverGetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + 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 NvRam store to match the new high part + // + return EfiSetVariable ( + mEfiMtcName, + &mEfiMtcGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT32), + HighCount + ); + +} + +STATIC +VOID +EFIAPI +EfiMtcEventHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Monotonic count event handler. This handler updates the high monotonic count. + +Arguments: + + Event The event to handle + Context The event context + +Returns: + + EFI_SUCCESS The event has been handled properly + EFI_NOT_FOUND An error occurred updating the variable. + +--*/ +{ + UINT32 HighCount; + + MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount); +} + +EFI_STATUS +EFIAPI +MonotonicCounterDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + +Arguments: + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) + +Returns: + +--*/ +{ + EFI_STATUS Status; + UINT32 HighCount; + UINTN BufferSize; + + // + // Make sure the Monotonic Counter Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMonotonicCounterArchProtocolGuid); + + // + // Initialize event to handle overflows + // + 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 ( + mEfiMtcName, + &mEfiMtcGuid, + 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. + // + Status = 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/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h new file mode 100644 index 0000000000..c1ef509f77 --- /dev/null +++ b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h @@ -0,0 +1,54 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MonotonicCounter.h + +Abstract: + + Produces the Monotonic Counter services as defined in the DXE CIS + +--*/ + +#ifndef _MONOTONIC_COUNTER_DRIVER_H_ +#define _MONOTONIC_COUNTER_DRIVER_H_ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include + +// +// Function Prototypes +// +EFI_STATUS +EFIAPI +MonotonicCounterDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +#endif diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf new file mode 100644 index 0000000000..f16951a2e3 --- /dev/null +++ b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf @@ -0,0 +1,97 @@ +#/** @file +# Component description file for MonotonicCounter module. +# +# This module produces UEFI Monotonic Counter Boot and Runtime Services. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MonotonicCounter + FILE_GUID = AD608272-D07F-4964-801E-7BD3B7888652 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = MonotonicCounterDriverInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + MonotonicCounter.h + MonotonicCounter.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + DebugLib + UefiRuntimeLib + UefiDriverEntryPoint + BaseLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiMonotonicCounterArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid + diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa new file mode 100644 index 0000000000..291f2ea680 --- /dev/null +++ b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa @@ -0,0 +1,65 @@ + + + + MonotonicCounter + DXE_RUNTIME_DRIVER + AD608272-D07F-4964-801E-7BD3B7888652 + 1.0 + Component description file for MonotonicCounter module. + This module produces UEFI Monotonic Counter Boot and Runtime Services. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + MonotonicCounter + + + + BaseLib + + + UefiDriverEntryPoint + + + UefiRuntimeLib + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiBootServicesTableLib + + + UefiRuntimeServicesTableLib + + + + MonotonicCounter.c + MonotonicCounter.h + MonotonicCounter.dxs + + + + + + + gEfiMonotonicCounterArchProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + MonotonicCounterDriverInitialize + + + -- 2.39.2