3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Produced the Monotonic Counter Services as defined in the DXE CIS
24 #include "MonotonicCounter.h"
27 // The Monotonic Counter Handle
29 EFI_HANDLE mMonotonicCounterHandle
= NULL
;
32 // The current Monotonic count value
37 // Event to use to update the Mtc's high part when wrapping
39 EFI_EVENT mEfiMtcEvent
;
42 // EfiMtcName - Variable name of the MTC value
44 CHAR16
*mEfiMtcName
= (CHAR16
*) L
"MTC";
47 // EfiMtcGuid - Guid of the MTC value
49 EFI_GUID mEfiMtcGuid
= { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } };
56 MonotonicCounterDriverGetNextMonotonicCount (
72 // Can not be called after ExitBootServices()
74 if (EfiAtRuntime ()) {
75 return EFI_UNSUPPORTED
;
78 // Check input parameters
81 return EFI_INVALID_PARAMETER
;
84 // Update the monotonic counter with a lock
86 OldTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
89 gBS
->RestoreTPL (OldTpl
);
92 // If the MSB bit of the low part toggled, then signal that the high
93 // part needs updated now
95 if ((((UINT32
) mEfiMtc
) ^ ((UINT32
) *Count
)) & 0x80000000) {
96 gBS
->SignalEvent (mEfiMtcEvent
);
105 Call back function on EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
107 Fixup internal data so that the driver is callable in EFI runtime
108 in virtual mode. Convert gRT to virtual address. gRT is from
109 UefiRuntimeServicesTableLib class. It is not fixed up by
110 UefiRuntimeServicesTableLib instance.
112 @param Event Event whose notification function is being invoked.
113 @param Context The context of the Notification context. Not used in
114 this call back function.
119 MonotonicCounterDriverSetVirtualAddressMap (
133 gRT
->ConvertPointer (0, (VOID
**) &gRT
);
140 MonotonicCounterDriverGetNextHighMonotonicCount (
141 OUT UINT32
*HighCount
157 // Check input parameters
159 if (HighCount
== NULL
) {
160 return EFI_INVALID_PARAMETER
;
163 if (!EfiAtRuntime ()) {
165 // Use a lock if called before ExitBootServices()
167 OldTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
168 *HighCount
= (UINT32
) RShiftU64 (mEfiMtc
, 32) + 1;
169 mEfiMtc
= LShiftU64 (*HighCount
, 32);
170 gBS
->RestoreTPL (OldTpl
);
172 *HighCount
= (UINT32
) RShiftU64 (mEfiMtc
, 32) + 1;
173 mEfiMtc
= LShiftU64 (*HighCount
, 32);
176 // Update the NvRam store to match the new high part
178 Status
= gRT
->SetVariable (
181 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
199 Monotonic count event handler. This handler updates the high monotonic count.
203 Event The event to handle
204 Context The event context
208 EFI_SUCCESS The event has been handled properly
209 EFI_NOT_FOUND An error occurred updating the variable.
215 MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount
);
220 MonotonicCounterDriverInitialize (
221 IN EFI_HANDLE ImageHandle
,
222 IN EFI_SYSTEM_TABLE
*SystemTable
229 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
240 // Make sure the Monotonic Counter Architectural Protocol is not already installed in the system
242 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gEfiMonotonicCounterArchProtocolGuid
);
245 // Initialize event to handle overflows
247 Status
= gBS
->CreateEvent (
248 EFI_EVENT_NOTIFY_SIGNAL
,
255 ASSERT_EFI_ERROR (Status
);
258 // Read the last high part
260 BufferSize
= sizeof (UINT32
);
261 Status
= gRT
->GetVariable (
268 if (EFI_ERROR (Status
)) {
272 // Set the current value
274 mEfiMtc
= LShiftU64 (HighCount
, 32);
277 // Increment the upper 32 bits for this boot
278 // Continue even if it fails. It will only fail if the variable services are
281 Status
= MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount
);
284 // Fill in the EFI Boot Services and EFI Runtime Services Monotonic Counter Fields
286 gBS
->GetNextMonotonicCount
= MonotonicCounterDriverGetNextMonotonicCount
;
287 gRT
->GetNextHighMonotonicCount
= MonotonicCounterDriverGetNextHighMonotonicCount
;
290 // Install the Monotonic Counter Architctural Protocol onto a new handle
292 Status
= gBS
->InstallMultipleProtocolInterfaces (
293 &mMonotonicCounterHandle
,
294 &gEfiMonotonicCounterArchProtocolGuid
,
298 ASSERT_EFI_ERROR (Status
);