]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c
IntelFrameworkModulePkg/BdsDxe: Remove the useless Perf codes
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / Performance.c
1 /** @file
2 This file include the file which can help to get the system
3 performance, all the function will only include if the performance
4 switch is set.
5
6 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "InternalBdsLib.h"
18
19 PERF_HEADER mPerfHeader;
20 PERF_DATA mPerfData;
21 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase = 0x0FFFFFFFFULL;
22
23 /**
24 Get the short verion of PDB file name to be
25 used in performance data logging.
26
27 @param PdbFileName The long PDB file name.
28 @param GaugeString The output string to be logged by performance logger.
29
30 **/
31 VOID
32 GetShortPdbFileName (
33 IN CONST CHAR8 *PdbFileName,
34 OUT CHAR8 *GaugeString
35 )
36 {
37 UINTN Index;
38 UINTN Index1;
39 UINTN StartIndex;
40 UINTN EndIndex;
41
42 if (PdbFileName == NULL) {
43 AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");
44 } else {
45 StartIndex = 0;
46 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
47 ;
48
49 for (Index = 0; PdbFileName[Index] != 0; Index++) {
50 if (PdbFileName[Index] == '\\') {
51 StartIndex = Index + 1;
52 }
53
54 if (PdbFileName[Index] == '.') {
55 EndIndex = Index;
56 }
57 }
58
59 Index1 = 0;
60 for (Index = StartIndex; Index < EndIndex; Index++) {
61 GaugeString[Index1] = PdbFileName[Index];
62 Index1++;
63 if (Index1 == PERF_TOKEN_LENGTH) {
64 break;
65 }
66 }
67
68 GaugeString[Index1] = 0;
69 }
70
71 return ;
72 }
73
74 /**
75 Get the name from the Driver handle, which can be a handle with
76 EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.
77 This name can be used in performance data logging.
78
79 @param Handle Driver handle.
80 @param GaugeString The output string to be logged by performance logger.
81
82 **/
83 VOID
84 GetNameFromHandle (
85 IN EFI_HANDLE Handle,
86 OUT CHAR8 *GaugeString
87 )
88 {
89 EFI_STATUS Status;
90 EFI_LOADED_IMAGE_PROTOCOL *Image;
91 CHAR8 *PdbFileName;
92 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
93
94 AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");
95
96 //
97 // Get handle name from image protocol
98 //
99 Status = gBS->HandleProtocol (
100 Handle,
101 &gEfiLoadedImageProtocolGuid,
102 (VOID **) &Image
103 );
104
105 if (EFI_ERROR (Status)) {
106 Status = gBS->OpenProtocol (
107 Handle,
108 &gEfiDriverBindingProtocolGuid,
109 (VOID **) &DriverBinding,
110 NULL,
111 NULL,
112 EFI_OPEN_PROTOCOL_GET_PROTOCOL
113 );
114 if (EFI_ERROR (Status)) {
115 return ;
116 }
117 //
118 // Get handle name from image protocol
119 //
120 Status = gBS->HandleProtocol (
121 DriverBinding->ImageHandle,
122 &gEfiLoadedImageProtocolGuid,
123 (VOID **) &Image
124 );
125 }
126
127 PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
128
129 if (PdbFileName != NULL) {
130 GetShortPdbFileName (PdbFileName, GaugeString);
131 }
132
133 return ;
134 }
135
136 /**
137
138 Writes performance data of booting into the allocated memory.
139 OS can process these records.
140
141 @param Event The triggered event.
142 @param Context Context for this event.
143
144 **/
145 VOID
146 EFIAPI
147 WriteBootToOsPerformanceData (
148 IN EFI_EVENT Event,
149 IN VOID *Context
150 )
151 {
152 EFI_STATUS Status;
153 UINT32 LimitCount;
154 EFI_HANDLE *Handles;
155 UINTN NoHandles;
156 CHAR8 GaugeString[PERF_TOKEN_SIZE];
157 UINT8 *Ptr;
158 UINT32 Index;
159 UINT64 Ticker;
160 UINT64 Freq;
161 UINT32 Duration;
162 UINTN LogEntryKey;
163 CONST VOID *Handle;
164 CONST CHAR8 *Token;
165 CONST CHAR8 *Module;
166 UINT64 StartTicker;
167 UINT64 EndTicker;
168 UINT64 StartValue;
169 UINT64 EndValue;
170 BOOLEAN CountUp;
171 UINTN VarSize;
172 BOOLEAN Found;
173
174 //
175 // Record the performance data for End of BDS
176 //
177 PERF_END(NULL, "BDS", NULL, 0);
178
179 //
180 // Retrieve time stamp count as early as possible
181 //
182 Ticker = GetPerformanceCounter ();
183
184 Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);
185
186 Freq = DivU64x32 (Freq, 1000);
187
188 mPerfHeader.CpuFreq = Freq;
189
190 //
191 // Record BDS raw performance data
192 //
193 if (EndValue >= StartValue) {
194 mPerfHeader.BDSRaw = Ticker - StartValue;
195 CountUp = TRUE;
196 } else {
197 mPerfHeader.BDSRaw = StartValue - Ticker;
198 CountUp = FALSE;
199 }
200
201 //
202 // Reset the entry count
203 //
204 mPerfHeader.Count = 0;
205
206 if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
207 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
208 Status = gRT->GetVariable (
209 L"PerfDataMemAddr",
210 &gPerformanceProtocolGuid,
211 NULL,
212 &VarSize,
213 &mAcpiLowMemoryBase
214 );
215 if (EFI_ERROR (Status)) {
216 //
217 // Fail to get the variable, return.
218 //
219 return;
220 }
221 }
222
223 //
224 // Put Detailed performance data into memory
225 //
226 Handles = NULL;
227 Status = gBS->LocateHandleBuffer (
228 AllHandles,
229 NULL,
230 NULL,
231 &NoHandles,
232 &Handles
233 );
234 if (EFI_ERROR (Status)) {
235 return ;
236 }
237
238 Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
239 LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
240
241 //
242 // Get performance data
243 //
244 LogEntryKey = 0;
245 while ((LogEntryKey = GetPerformanceMeasurement (
246 LogEntryKey,
247 &Handle,
248 &Token,
249 &Module,
250 &StartTicker,
251 &EndTicker)) != 0) {
252 if (EndTicker != 0) {
253 if (StartTicker == 1) {
254 StartTicker = StartValue;
255 }
256 if (EndTicker == 1) {
257 EndTicker = StartValue;
258 }
259 Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
260
261 Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
262 if (Duration == 0) {
263 continue;
264 }
265
266 ZeroMem (&mPerfData, sizeof (PERF_DATA));
267
268 mPerfData.Duration = Duration;
269
270 //
271 // See if the Handle is in the handle buffer
272 //
273 Found = FALSE;
274 for (Index = 0; Index < NoHandles; Index++) {
275 if (Handle == Handles[Index]) {
276 GetNameFromHandle (Handles[Index], GaugeString);
277 AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);
278 Found = TRUE;
279 break;
280 }
281 }
282
283 if (!Found) {
284 AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);
285 }
286
287 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
288 Ptr += sizeof (PERF_DATA);
289
290 mPerfHeader.Count++;
291 if (mPerfHeader.Count == LimitCount) {
292 goto Done;
293 }
294 }
295 }
296
297 Done:
298
299 FreePool (Handles);
300
301 mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
302
303 //
304 // Put performance data to Reserved memory
305 //
306 CopyMem (
307 (UINTN *) (UINTN) mAcpiLowMemoryBase,
308 &mPerfHeader,
309 sizeof (PERF_HEADER)
310 );
311
312 return ;
313 }