]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
3644824e7bd1c5bc811045f083e0f8b4fadc5e60
[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 - 2012, 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
149 @param Handle Pointer to environment specific context used
150 to identify the component being measured.
151 @param Token Pointer to a Null-terminated ASCII string
152 that identifies the component being measured.
153 @param Module Pointer to a Null-terminated ASCII string
154 that identifies the module being measured.
155 @param TimeStamp 64-bit time stamp.
156
157 @retval RETURN_SUCCESS The end of the measurement was recorded.
158 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
159
160 **/
161 RETURN_STATUS
162 EFIAPI
163 EndPerformanceMeasurement (
164 IN CONST VOID *Handle, OPTIONAL
165 IN CONST CHAR8 *Token, OPTIONAL
166 IN CONST CHAR8 *Module, OPTIONAL
167 IN UINT64 TimeStamp
168 )
169 {
170 EFI_STATUS Status;
171
172 Status = GetPerformanceProtocol ();
173 if (EFI_ERROR (Status)) {
174 return RETURN_NOT_FOUND;
175 }
176
177 Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);
178
179 return (RETURN_STATUS) Status;
180 }
181
182 /**
183 Attempts to retrieve a performance measurement log entry from the performance measurement log.
184
185 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
186 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
187 and the key for the second entry in the log is returned. If the performance log is empty,
188 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
189 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
190 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
191 retrieved and an implementation specific non-zero key value that specifies the end of the performance
192 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
193 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
194 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
195 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
196 If Handle is NULL, then ASSERT().
197 If Token is NULL, then ASSERT().
198 If Module is NULL, then ASSERT().
199 If StartTimeStamp is NULL, then ASSERT().
200 If EndTimeStamp is NULL, then ASSERT().
201
202 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
203 0, then the first performance measurement log entry is retrieved.
204 On exit, the key of the next performance log entry.
205 @param Handle Pointer to environment specific context used to identify the component
206 being measured.
207 @param Token Pointer to a Null-terminated ASCII string that identifies the component
208 being measured.
209 @param Module Pointer to a Null-terminated ASCII string that identifies the module
210 being measured.
211 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
212 was started.
213 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
214 was ended.
215
216 @return The key for the next performance log entry (in general case).
217
218 **/
219 UINTN
220 EFIAPI
221 GetPerformanceMeasurement (
222 IN UINTN LogEntryKey,
223 OUT CONST VOID **Handle,
224 OUT CONST CHAR8 **Token,
225 OUT CONST CHAR8 **Module,
226 OUT UINT64 *StartTimeStamp,
227 OUT UINT64 *EndTimeStamp
228 )
229 {
230 EFI_STATUS Status;
231 GAUGE_DATA_ENTRY *GaugeData;
232
233 GaugeData = NULL;
234
235 ASSERT (Handle != NULL);
236 ASSERT (Token != NULL);
237 ASSERT (Module != NULL);
238 ASSERT (StartTimeStamp != NULL);
239 ASSERT (EndTimeStamp != NULL);
240
241 Status = GetPerformanceProtocol ();
242 if (EFI_ERROR (Status)) {
243 return 0;
244 }
245
246 Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData);
247
248 //
249 // Make sure that LogEntryKey is a valid log entry key,
250 //
251 ASSERT (Status != EFI_INVALID_PARAMETER);
252
253 if (EFI_ERROR (Status)) {
254 //
255 // The LogEntryKey is the last entry (equals to the total entry number).
256 //
257 return 0;
258 }
259
260 ASSERT (GaugeData != NULL);
261
262 *Handle = (VOID *) (UINTN) GaugeData->Handle;
263 *Token = GaugeData->Token;
264 *Module = GaugeData->Module;
265 *StartTimeStamp = GaugeData->StartTimeStamp;
266 *EndTimeStamp = GaugeData->EndTimeStamp;
267
268 return LogEntryKey;
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 }