Add MonotonicCounter driver, which produces MonotonicCounter arch protocols
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 6 Jul 2007 09:15:13 +0000 (09:15 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 6 Jul 2007 09:15:13 +0000 (09:15 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3115 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c [new file with mode: 0644]
MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h [new file with mode: 0644]
MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf [new file with mode: 0644]
MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa [new file with mode: 0644]

diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.c
new file mode 100644 (file)
index 0000000..31efab3
--- /dev/null
@@ -0,0 +1,299 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  MonotonicCounter.c\r
+\r
+Abstract:\r
+\r
+  Produced the Monotonic Counter Services as defined in the DXE CIS\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+#include "MonotonicCounter.h"\r
+\r
+//\r
+// The Monotonic Counter Handle\r
+//\r
+EFI_HANDLE  mMonotonicCounterHandle = NULL;\r
+\r
+//\r
+// The current Monotonic count value\r
+//\r
+UINT64      mEfiMtc;\r
+\r
+//\r
+// Event to use to update the Mtc's high part when wrapping\r
+//\r
+EFI_EVENT   mEfiMtcEvent;\r
+\r
+//\r
+// EfiMtcName - Variable name of the MTC value\r
+//\r
+CHAR16      *mEfiMtcName = (CHAR16 *) L"MTC";\r
+\r
+//\r
+// EfiMtcGuid - Guid of the MTC value\r
+//\r
+EFI_GUID    mEfiMtcGuid = { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } };\r
+\r
+//\r
+// Worker functions\r
+//\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+MonotonicCounterDriverGetNextMonotonicCount (\r
+  OUT UINT64  *Count\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_TPL OldTpl;\r
+\r
+  //\r
+  // Can not be called after ExitBootServices()\r
+  //\r
+  if (EfiAtRuntime ()) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Check input parameters\r
+  //\r
+  if (Count == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Update the monotonic counter with a lock\r
+  //\r
+  OldTpl  = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+  *Count  = mEfiMtc;\r
+  mEfiMtc++;\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  //\r
+  // If the MSB bit of the low part toggled, then signal that the high\r
+  // part needs updated now\r
+  //\r
+  if ((((UINT32) mEfiMtc) ^ ((UINT32) *Count)) & 0x80000000) {\r
+    gBS->SignalEvent (mEfiMtcEvent);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Returns the next high 32 bits of the platform's monotonic counter.\r
+\r
+  The GetNextHighMonotonicCount() function returns the next high 32 bits\r
+  of the platform's monotonic counter. The platform's monotonic counter is\r
+  comprised of two 32 bit quantities:  the high 32 bits and the low 32 bits.\r
+  During boot service time the low 32 bit value is volatile:  it is reset to\r
+  zero on every system reset and is increased by 1 on every call to GetNextMonotonicCount().\r
+  The high 32 bit value is non-volatile and is increased by 1 whenever the system resets\r
+  or whenever the low 32 bit count [returned by GetNextMonoticCount()] overflows.\r
+  The GetNextMonotonicCount() function is only available at boot services time.\r
+  If the operating system wishes to extend the platform monotonic counter to runtime,\r
+  it may do so by utilizing GetNextHighMonotonicCount().  To do this, before calling\r
+  ExitBootServices() the operating system would call GetNextMonotonicCount() to obtain\r
+  the current platform monotonic count.  The operating system would then provide an\r
+  interface that returns the next count by:\r
+    Adding 1 to the last count.\r
+    Before the lower 32 bits of the count overflows, call GetNextHighMonotonicCount().\r
+    This will increase the high 32 bits of the platform's non-volatile portion of the monotonic\r
+    count by 1.\r
+\r
+  This function may only be called at Runtime.\r
+\r
+  @param[out]   HighCount      Pointer to returned value.\r
+\r
+  @retval EFI_INVALID_PARAMETER If HighCount is NULL.\r
+  @retval EFI_SUCCESS           Operation is successful.\r
+  @retval EFI_OUT_OF_RESOURCES  If variable service reports that not enough storage\r
+                                is available to hold the variable and its data.\r
+  @retval EFI_DEVICE_ERROR      The variable could not be saved due to a hardware failure.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+MonotonicCounterDriverGetNextHighMonotonicCount (\r
+  OUT UINT32  *HighCount\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_TPL     OldTpl;\r
+\r
+  //\r
+  // Check input parameters\r
+  //\r
+  if (HighCount == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!EfiAtRuntime ()) {\r
+    //\r
+    // Use a lock if called before ExitBootServices()\r
+    //\r
+    OldTpl      = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;\r
+    mEfiMtc     = LShiftU64 (*HighCount, 32);\r
+    gBS->RestoreTPL (OldTpl);\r
+  } else {\r
+    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;\r
+    mEfiMtc     = LShiftU64 (*HighCount, 32);\r
+  }\r
+  //\r
+  // Update the NvRam store to match the new high part\r
+  //\r
+  return EfiSetVariable (\r
+           mEfiMtcName,\r
+           &mEfiMtcGuid,\r
+           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+           sizeof (UINT32),\r
+           HighCount\r
+           );\r
+\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+EfiMtcEventHandler (\r
+  IN EFI_EVENT                Event,\r
+  IN VOID                     *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Monotonic count event handler.  This handler updates the high monotonic count.\r
+\r
+Arguments:\r
+\r
+  Event         The event to handle\r
+  Context       The event context\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       The event has been handled properly\r
+  EFI_NOT_FOUND     An error occurred updating the variable.\r
+\r
+--*/\r
+{\r
+  UINT32  HighCount;\r
+\r
+  MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MonotonicCounterDriverInitialize (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      HighCount;\r
+  UINTN       BufferSize;\r
+\r
+  //\r
+  // Make sure the Monotonic Counter Architectural Protocol is not already installed in the system\r
+  //\r
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMonotonicCounterArchProtocolGuid);\r
+\r
+  //\r
+  // Initialize event to handle overflows\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  EfiMtcEventHandler,\r
+                  NULL,\r
+                  &mEfiMtcEvent\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Read the last high part\r
+  //\r
+  BufferSize = sizeof (UINT32);\r
+  Status = EfiGetVariable (\r
+             mEfiMtcName,\r
+             &mEfiMtcGuid,\r
+             NULL,\r
+             &BufferSize,\r
+             &HighCount\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    HighCount = 0;\r
+  }\r
+  //\r
+  // Set the current value\r
+  //\r
+  mEfiMtc = LShiftU64 (HighCount, 32);\r
+\r
+  //\r
+  // Increment the upper 32 bits for this boot\r
+  // Continue even if it fails.  It will only fail if the variable services are\r
+  // not functional.\r
+  //\r
+  Status = MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);\r
+\r
+  //\r
+  // Fill in the EFI Boot Services and EFI Runtime Services Monotonic Counter Fields\r
+  //\r
+  gBS->GetNextMonotonicCount      = MonotonicCounterDriverGetNextMonotonicCount;\r
+  gRT->GetNextHighMonotonicCount  = MonotonicCounterDriverGetNextHighMonotonicCount;\r
+\r
+  //\r
+  // Install the Monotonic Counter Architctural Protocol onto a new handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mMonotonicCounterHandle,\r
+                  &gEfiMonotonicCounterArchProtocolGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.h
new file mode 100644 (file)
index 0000000..c1ef509
--- /dev/null
@@ -0,0 +1,54 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  MonotonicCounter.h\r
+\r
+Abstract:\r
+\r
+  Produces the Monotonic Counter services as defined in the DXE CIS\r
+\r
+--*/\r
+\r
+#ifndef _MONOTONIC_COUNTER_DRIVER_H_\r
+#define _MONOTONIC_COUNTER_DRIVER_H_\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/MonotonicCounter.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+//\r
+// Function Prototypes\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+MonotonicCounterDriverInitialize (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.inf
new file mode 100644 (file)
index 0000000..f16951a
--- /dev/null
@@ -0,0 +1,97 @@
+#/** @file\r
+# Component description file for MonotonicCounter module.\r
+#\r
+# This module produces UEFI Monotonic Counter Boot and Runtime Services.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = MonotonicCounter\r
+  FILE_GUID                      = AD608272-D07F-4964-801E-7BD3B7888652\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = MonotonicCounterDriverInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  MonotonicCounter.h\r
+  MonotonicCounter.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+  UefiRuntimeLib\r
+  UefiDriverEntryPoint\r
+  BaseLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiMonotonicCounterArchProtocolGuid          # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid\r
+\r
diff --git a/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa b/MdeModulePkg/Universal/MonotonicCounterDxe/MonotonicCounter.msa
new file mode 100644 (file)
index 0000000..291f2ea
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>MonotonicCounter</ModuleName>\r
+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>\r
+    <GuidValue>AD608272-D07F-4964-801E-7BD3B7888652</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for MonotonicCounter module.</Abstract>\r
+    <Description>This module produces UEFI Monotonic Counter Boot and Runtime Services.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>MonotonicCounter</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>MonotonicCounter.c</Filename>\r
+    <Filename>MonotonicCounter.h</Filename>\r
+    <Filename>MonotonicCounter.dxs</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiMonotonicCounterArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>MonotonicCounterDriverInitialize</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r