]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
Add performance library instances for SMM performance measurement.
[mirror_edk2.git] / MdeModulePkg / Library / SmmPerformanceLib / SmmPerformanceLib.c
1 /** @file
2 Performance Library used in SMM phase.
3
4 This library instance provides infrastructure for SMM drivers to log performance
5 data. It consumes SMM Performance Protocol published by SmmCorePerformanceLib
6 to log performance data. If Performance Protocol is not available, it does not log any
7 performance information.
8
9 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
10 This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
14
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17
18 **/
19
20
21 #include <Guid/Performance.h>
22
23 #include <Library/PerformanceLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/SmmServicesTableLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/BaseMemoryLib.h>
28
29 #include <Protocol/SmmCommunication.h>
30
31 //
32 // The cached performance protocol interface.
33 //
34 PERFORMANCE_PROTOCOL *mPerformance = NULL;
35 BOOLEAN mPerformanceMeasurementEnabled;
36
37
38 /**
39 The constructor function initializes Performance infrastructure for DXE phase.
40
41 The constructor function publishes Performance protocol, allocates memory to log DXE performance
42 and merges PEI performance data to DXE performance log.
43 It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.
44
45 @param ImageHandle The firmware allocated handle for the EFI image.
46 @param SystemTable A pointer to the EFI System Table.
47
48 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
49
50 **/
51 EFI_STATUS
52 EFIAPI
53 SmmPerformanceLibConstructor (
54 IN EFI_HANDLE ImageHandle,
55 IN EFI_SYSTEM_TABLE *SystemTable
56 )
57 {
58
59 mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
60
61 return EFI_SUCCESS;
62 }
63
64 /**
65 The constructor function caches the pointer to Performance protocol.
66
67 The constructor function locates SMM erformance protocol from the SMM protocol database.
68 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
69
70 @retval EFI_SUCCESS Performance protocol is successfully located.
71 @retval Other Performance protocol is not located to log performance.
72
73 **/
74 EFI_STATUS
75 GetPerformanceProtocol (
76 VOID
77 )
78 {
79 EFI_STATUS Status;
80 PERFORMANCE_PROTOCOL *Performance;
81
82 if (mPerformance != NULL) {
83 return EFI_SUCCESS;
84 }
85
86 Status = gSmst->SmmLocateProtocol (&gSmmPerformanceProtocolGuid, NULL, (VOID **) &Performance);
87 if (!EFI_ERROR (Status)) {
88 ASSERT (Performance != NULL);
89 //
90 // Cache performance protocol.
91 //
92 mPerformance = Performance;
93 }
94
95 return Status;
96 }
97
98 /**
99 Creates a record for the beginning of a performance measurement.
100
101 Creates a record that contains the Handle, Token, and Module.
102 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
103 If TimeStamp is zero, then this function reads the current time stamp
104 and adds that time stamp value to the record as the start time.
105
106 @param Handle Pointer to environment specific context used
107 to identify the component being measured.
108 @param Token Pointer to a Null-terminated ASCII string
109 that identifies the component being measured.
110 @param Module Pointer to a Null-terminated ASCII string
111 that identifies the module being measured.
112 @param TimeStamp 64-bit time stamp.
113
114 @retval RETURN_SUCCESS The start of the measurement was recorded.
115 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
116
117 **/
118 RETURN_STATUS
119 EFIAPI
120 StartPerformanceMeasurement (
121 IN CONST VOID *Handle, OPTIONAL
122 IN CONST CHAR8 *Token, OPTIONAL
123 IN CONST CHAR8 *Module, OPTIONAL
124 IN UINT64 TimeStamp
125 )
126 {
127 EFI_STATUS Status;
128
129 Status = GetPerformanceProtocol ();
130 if (EFI_ERROR (Status)) {
131 return RETURN_OUT_OF_RESOURCES;
132 }
133
134 Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);
135
136 return (RETURN_STATUS) Status;
137 }
138
139 /**
140 Fills in the end time of a performance measurement.
141
142 Looks up the record that matches Handle, Token, and Module.
143 If the record can not be found then return RETURN_NOT_FOUND.
144 If the record is found and TimeStamp is not zero,
145 then TimeStamp is added to the record as the end time.
146 If the record is found and TimeStamp is zero, then this function reads
147 the current time stamp and adds that time stamp value to the record as the end time.
148 If this function is called multiple times for the same record, then the end time is overwritten.
149
150 @param Handle Pointer to environment specific context used
151 to identify the component being measured.
152 @param Token Pointer to a Null-terminated ASCII string
153 that identifies the component being measured.
154 @param Module Pointer to a Null-terminated ASCII string
155 that identifies the module being measured.
156 @param TimeStamp 64-bit time stamp.
157
158 @retval RETURN_SUCCESS The end of the measurement was recorded.
159 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
160
161 **/
162 RETURN_STATUS
163 EFIAPI
164 EndPerformanceMeasurement (
165 IN CONST VOID *Handle, OPTIONAL
166 IN CONST CHAR8 *Token, OPTIONAL
167 IN CONST CHAR8 *Module, OPTIONAL
168 IN UINT64 TimeStamp
169 )
170 {
171 EFI_STATUS Status;
172
173 Status = GetPerformanceProtocol ();
174 if (EFI_ERROR (Status)) {
175 return RETURN_NOT_FOUND;
176 }
177
178 Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);
179
180 return (RETURN_STATUS) Status;
181 }
182
183 /**
184 Attempts to retrieve a performance measurement log entry from the performance measurement log.
185
186 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
187 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
188 and the key for the second entry in the log is returned. If the performance log is empty,
189 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
190 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
191 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
192 retrieved and an implementation specific non-zero key value that specifies the end of the performance
193 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
194 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
195 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
196 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
197 If Handle is NULL, then ASSERT().
198 If Token is NULL, then ASSERT().
199 If Module is NULL, then ASSERT().
200 If StartTimeStamp is NULL, then ASSERT().
201 If EndTimeStamp is NULL, then ASSERT().
202
203 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
204 0, then the first performance measurement log entry is retrieved.
205 On exit, the key of the next performance log entry.
206 @param Handle Pointer to environment specific context used to identify the component
207 being measured.
208 @param Token Pointer to a Null-terminated ASCII string that identifies the component
209 being measured.
210 @param Module Pointer to a Null-terminated ASCII string that identifies the module
211 being measured.
212 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
213 was started.
214 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
215 was ended.
216
217 @return The key for the next performance log entry (in general case).
218
219 **/
220 UINTN
221 EFIAPI
222 GetPerformanceMeasurement (
223 IN UINTN LogEntryKey,
224 OUT CONST VOID **Handle,
225 OUT CONST CHAR8 **Token,
226 OUT CONST CHAR8 **Module,
227 OUT UINT64 *StartTimeStamp,
228 OUT UINT64 *EndTimeStamp
229 )
230 {
231 EFI_STATUS Status;
232 GAUGE_DATA_ENTRY *GaugeData;
233
234 GaugeData = NULL;
235
236 ASSERT (Handle != NULL);
237 ASSERT (Token != NULL);
238 ASSERT (Module != NULL);
239 ASSERT (StartTimeStamp != NULL);
240 ASSERT (EndTimeStamp != NULL);
241
242 Status = GetPerformanceProtocol ();
243 if (EFI_ERROR (Status)) {
244 return 0;
245 }
246
247 Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData);
248
249 //
250 // Make sure that LogEntryKey is a valid log entry key,
251 //
252 ASSERT (Status != EFI_INVALID_PARAMETER);
253
254 if (EFI_ERROR (Status)) {
255 //
256 // The LogEntryKey is the last entry (equals to the total entry number).
257 //
258 return 0;
259 }
260
261 ASSERT (GaugeData != NULL);
262
263 *Handle = (VOID *) (UINTN) GaugeData->Handle;
264 *Token = GaugeData->Token;
265 *Module = GaugeData->Module;
266 *StartTimeStamp = GaugeData->StartTimeStamp;
267 *EndTimeStamp = GaugeData->EndTimeStamp;
268
269 }
270
271 /**
272 Returns TRUE if the performance measurement macros are enabled.
273
274 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
275 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
276
277 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
278 PcdPerformanceLibraryPropertyMask is set.
279 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
280 PcdPerformanceLibraryPropertyMask is clear.
281
282 **/
283 BOOLEAN
284 EFIAPI
285 PerformanceMeasurementEnabled (
286 VOID
287 )
288 {
289 return mPerformanceMeasurementEnabled;
290 }