]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/TimestampDxe/TimestampDxe.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / TimestampDxe / TimestampDxe.c
1 /** @file
2 Implementation of Timestamp Protocol using UEFI APIs.
3
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Uefi.h>
10 #include <Library/DebugLib.h>
11 #include <Library/UefiDriverEntryPoint.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/TimerLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Protocol/Timestamp.h>
16
17 //
18 // The StartValue in TimerLib
19 //
20 UINT64 mTimerLibStartValue = 0;
21
22 //
23 // The EndValue in TimerLib
24 //
25 UINT64 mTimerLibEndValue = 0;
26
27 //
28 // The properties of timestamp
29 //
30 EFI_TIMESTAMP_PROPERTIES mTimestampProperties = {
31 0,
32 0
33 };
34
35 /**
36 Retrieves the current value of a 64-bit free running timestamp counter.
37
38 The counter shall count up in proportion to the amount of time that has passed. The counter value
39 will always roll over to zero. The properties of the counter can be retrieved from GetProperties().
40 The caller should be prepared for the function to return the same value twice across successive calls.
41 The counter value will not go backwards other than when wrapping, as defined by EndValue in GetProperties().
42 The frequency of the returned timestamp counter value must remain constant. Power management operations that
43 affect clocking must not change the returned counter frequency. The quantization of counter value updates may
44 vary as long as the value reflecting time passed remains consistent.
45
46 @retval The current value of the free running timestamp counter.
47
48 **/
49 UINT64
50 EFIAPI
51 TimestampDriverGetTimestamp (
52 VOID
53 )
54 {
55 //
56 // The timestamp of Timestamp Protocol
57 //
58 UINT64 TimestampValue;
59 TimestampValue = 0;
60
61 //
62 // Get the timestamp
63 //
64 if (mTimerLibStartValue > mTimerLibEndValue) {
65 TimestampValue = mTimerLibStartValue - GetPerformanceCounter();
66 } else {
67 TimestampValue = GetPerformanceCounter() - mTimerLibStartValue;
68 }
69
70 return TimestampValue;
71 }
72
73 /**
74 Obtains timestamp counter properties including frequency and value limits.
75
76 @param[out] Properties The properties of the timestamp counter.
77
78 @retval EFI_SUCCESS The properties were successfully retrieved.
79 @retval EFI_DEVICE_ERROR An error occurred trying to retrieve the properties of the timestamp
80 counter subsystem. Properties is not pedated.
81 @retval EFI_INVALID_PARAMETER Properties is NULL.
82
83 **/
84 EFI_STATUS
85 EFIAPI
86 TimestampDriverGetProperties(
87 OUT EFI_TIMESTAMP_PROPERTIES *Properties
88 )
89 {
90 if (Properties == NULL) {
91 return EFI_INVALID_PARAMETER;
92 }
93
94 //
95 // Get timestamp properties
96 //
97 CopyMem((VOID *) Properties, (VOID *) &mTimestampProperties, sizeof (mTimestampProperties));
98
99 return EFI_SUCCESS;
100 }
101
102 //
103 // The Timestamp Protocol instance produced by this driver
104 //
105 EFI_TIMESTAMP_PROTOCOL mTimestamp = {
106 TimestampDriverGetTimestamp,
107 TimestampDriverGetProperties
108 };
109
110 /**
111 Entry point of the Timestamp Protocol driver.
112
113 @param ImageHandle The image handle of this driver.
114 @param SystemTable The pointer of EFI_SYSTEM_TABLE.
115
116 @retval EFI_SUCCESS Watchdog Timer Architectural Protocol successfully installed.
117
118 **/
119 EFI_STATUS
120 EFIAPI
121 TimestampDriverInitialize (
122 IN EFI_HANDLE ImageHandle,
123 IN EFI_SYSTEM_TABLE *SystemTable
124 )
125 {
126 EFI_STATUS Status;
127
128 EFI_HANDLE TimestampHandle;
129 TimestampHandle = NULL;
130
131 //
132 // Get the start value, end value and frequency in Timerlib
133 //
134 mTimestampProperties.Frequency = GetPerformanceCounterProperties(&mTimerLibStartValue, &mTimerLibEndValue);
135
136 //
137 // Set the EndValue
138 //
139 if (mTimerLibEndValue > mTimerLibStartValue) {
140 mTimestampProperties.EndValue = mTimerLibEndValue - mTimerLibStartValue;
141 } else {
142 mTimestampProperties.EndValue = mTimerLibStartValue - mTimerLibEndValue;
143 }
144
145 DEBUG ((EFI_D_INFO, "TimerFrequency:0x%lx, TimerLibStartTime:0x%lx, TimerLibEndtime:0x%lx\n", mTimestampProperties.Frequency, mTimerLibStartValue, mTimerLibEndValue));
146
147 //
148 // Install the Timestamp Protocol onto a new handle
149 //
150 Status = gBS->InstallMultipleProtocolInterfaces (
151 &TimestampHandle,
152 &gEfiTimestampProtocolGuid,
153 &mTimestamp,
154 NULL
155 );
156
157 ASSERT_EFI_ERROR (Status);
158
159 return EFI_SUCCESS;
160 }