]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/DxePerformanceLib/PerformanceLib.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / EdkIIGlueLib / Library / DxePerformanceLib / PerformanceLib.c
1 /*++
2
3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
4 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
8
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.
11
12
13 Module Name:
14
15 PerformanceLib.c
16
17 Abstract:
18
19 Routines used by START_PERF() and END_PERF()
20
21 --*/
22
23 #include "EdkIIGlueDxe.h"
24
25
26 #define EFI_PERFORMANCE_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'R', 'F')
27 #define EFI_PERFORMANCE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'D', 'A')
28
29 #define GAUGE_DATA_FROM_GAUGE(_GaugeData) \
30 CR(_GaugeData, EFI_PERF_DATA_LIST, GaugeData, EFI_PERFORMANCE_DATA_SIGNATURE)
31
32 #define GAUGE_DATA_FROM_LINK(_link) \
33 CR(_link, EFI_PERF_DATA_LIST, Link, EFI_PERFORMANCE_DATA_SIGNATURE)
34
35 //
36 // Performace protocol instance containing record macro
37 //
38 #define EFI_PERFORMANCE_FROM_THIS(a) \
39 CR(a, EFI_PERFORMANCE_INSTANCE, Perf, EFI_PERFORMANCE_SIGNATURE)
40
41
42 typedef struct {
43 UINT32 Signature;
44 LIST_ENTRY Link;
45 EFI_GAUGE_DATA GaugeData;
46 } EFI_PERF_DATA_LIST;
47
48 //
49 // Performance protocol instance data structure
50 //
51 typedef struct {
52 UINTN Signature;
53 EFI_HANDLE Handle;
54 EFI_PERFORMANCE_PROTOCOL Perf;
55 UINT8 Phase;
56 } EFI_PERFORMANCE_INSTANCE;
57
58
59 LIST_ENTRY mPerfDataHead = INITIALIZE_LIST_HEAD_VARIABLE(mPerfDataHead);
60
61
62 STATIC
63 VOID
64 InternalGetTimerValue (
65 OUT UINT64 *TimerValue
66 )
67 /*++
68
69 Routine Description:
70
71 Set TimerValue with current tick.
72
73 Arguments:
74
75 TimerValue - Timer value to be set
76
77 Returns:
78
79 EFI_SUCCESS - TimerValue is set.
80
81 --*/
82 {
83 *TimerValue = AsmReadTsc ();
84 }
85
86
87 STATIC
88 VOID
89 GetShortPdbFileName (
90 CHAR8 *PdbFileName,
91 CHAR8 *GaugeString
92 )
93 /*++
94
95 Routine Description:
96
97 Arguments:
98
99 Returns:
100
101 --*/
102 {
103 UINTN Index;
104 UINTN Index1;
105 UINTN StartIndex;
106 UINTN EndIndex;
107
108 if (PdbFileName == NULL) {
109 AsciiStrCpy (GaugeString, " ");
110 } else {
111 StartIndex = 0;
112 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
113 ;
114
115 for (Index = 0; PdbFileName[Index] != 0; Index++) {
116 if (PdbFileName[Index] == '\\') {
117 StartIndex = Index + 1;
118 }
119
120 if (PdbFileName[Index] == '.') {
121 EndIndex = Index;
122 }
123 }
124
125 Index1 = 0;
126 for (Index = StartIndex; Index < EndIndex; Index++) {
127 GaugeString[Index1] = PdbFileName[Index];
128 Index1++;
129 if (Index1 == EFI_PERF_PDBFILENAME_LENGTH - 1) {
130 break;
131 }
132 }
133
134 GaugeString[Index1] = 0;
135 }
136
137 return;
138 }
139
140
141 STATIC
142 CHAR8 *
143 GetPdbPath (
144 VOID *ImageBase
145 )
146 /*++
147
148 Routine Description:
149
150 Located PDB path name in PE image
151
152 Arguments:
153
154 ImageBase - base of PE to search
155
156 Returns:
157
158 Pointer into image at offset of PDB file name if PDB file name is found,
159 Otherwise a pointer to an empty string.
160
161 --*/
162 {
163 CHAR8 *PdbPath;
164 UINT32 DirCount;
165 EFI_IMAGE_DOS_HEADER *DosHdr;
166 EFI_IMAGE_NT_HEADERS *NtHdr;
167 UINT16 Magic;
168 EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32;
169 EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64;
170 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
171 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
172 VOID *CodeViewEntryPointer;
173
174 CodeViewEntryPointer = NULL;
175 PdbPath = NULL;
176 DosHdr = ImageBase;
177 if (DosHdr && DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
178 NtHdr = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);
179 //
180 // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
181 // It is for backward-compatibility consideration, because
182 // some system will generate PE32+ image with PE32 Magic.
183 //
184 if (NtHdr->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
185 Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
186 } else if (NtHdr->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {
187 Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
188 } else if (NtHdr->FileHeader.Machine == IMAGE_FILE_MACHINE_X64) {
189 Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
190 } else {
191 Magic = NtHdr->OptionalHeader.Magic;
192 }
193 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
194 OptionalHdr32 = (VOID *) &NtHdr->OptionalHeader;
195 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
196 } else {
197 OptionalHdr64 = (VOID *) &NtHdr->OptionalHeader;
198 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
199 }
200
201 if (DirectoryEntry->VirtualAddress != 0) {
202 for (DirCount = 0;
203 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;
204 DirCount++
205 ) {
206 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
207 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
208 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);
209 switch (*(UINT32 *) CodeViewEntryPointer) {
210 case CODEVIEW_SIGNATURE_NB10:
211 PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
212 break;
213
214 case CODEVIEW_SIGNATURE_RSDS:
215 PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
216 break;
217
218 default:
219 break;
220 }
221 }
222 }
223 }
224 }
225
226 return PdbPath;
227 }
228
229
230 STATIC
231 VOID
232 GetNameFromHandle (
233 IN EFI_HANDLE Handle,
234 OUT CHAR8 *GaugeString
235 )
236 {
237 EFI_STATUS Status;
238 EFI_LOADED_IMAGE_PROTOCOL *Image;
239 CHAR8 *PdbFileName;
240 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
241
242 AsciiStrCpy (GaugeString, " ");
243
244 //
245 // Get handle name from image protocol
246 //
247 Status = gBS->HandleProtocol (
248 Handle,
249 &gEfiLoadedImageProtocolGuid,
250 (VOID**)&Image
251 );
252
253 if (EFI_ERROR (Status)) {
254 Status = gBS->OpenProtocol (
255 Handle,
256 &gEfiDriverBindingProtocolGuid,
257 (VOID **) &DriverBinding,
258 NULL,
259 NULL,
260 EFI_OPEN_PROTOCOL_GET_PROTOCOL
261 );
262 if (EFI_ERROR (Status)) {
263 return ;
264 }
265 //
266 // Get handle name from image protocol
267 //
268 Status = gBS->HandleProtocol (
269 DriverBinding->ImageHandle,
270 &gEfiLoadedImageProtocolGuid,
271 (VOID**)&Image
272 );
273 }
274
275 PdbFileName = GetPdbPath (Image->ImageBase);
276
277 if (PdbFileName != NULL) {
278 GetShortPdbFileName (PdbFileName, GaugeString);
279 }
280
281 return ;
282 }
283
284
285 EFI_PERF_DATA_LIST *
286 CreateDataNode (
287 IN EFI_HANDLE Handle,
288 IN UINT16 *Token,
289 IN UINT16 *Host
290 )
291 /*++
292
293 Routine Description:
294
295 Create a EFI_PERF_DATA_LIST data node.
296
297 Arguments:
298
299 Handle - Handle of gauge data
300 Token - Token of gauge data
301 Host - Host of gauge data
302
303 Returns:
304
305 Pointer to a data node created.
306
307 --*/
308 {
309 EFI_PERF_DATA_LIST *Node;
310
311 //
312 // Allocate a new image structure
313 //
314 Node = AllocateZeroPool (sizeof (EFI_PERF_DATA_LIST));
315 if (Node != NULL) {
316
317 Node->Signature = EFI_PERFORMANCE_DATA_SIGNATURE;
318
319 Node->GaugeData.Handle = Handle;
320
321 if (Token != NULL) {
322 StrCpy ((Node->GaugeData).Token, Token);
323 }
324
325 if (Host != NULL) {
326 StrCpy ((Node->GaugeData).Host, Host);
327 }
328
329 if (Handle != NULL) {
330 GetNameFromHandle (Handle, Node->GaugeData.PdbFileName);
331 }
332 }
333
334 return Node;
335 }
336
337
338 EFI_PERF_DATA_LIST *
339 GetDataNode (
340 IN EFI_HANDLE Handle,
341 IN UINT16 *Token,
342 IN UINT16 *Host,
343 IN EFI_GUID *GuidName,
344 IN EFI_GAUGE_DATA *PrevGauge
345 )
346 /*++
347
348 Routine Description:
349
350 Search gauge node list to find one node with matched handle, token, host and Guid name.
351
352 Arguments:
353
354 Handle - Handle to match
355 Token - Token to match
356 Host - Host to match
357 GuidName - Guid name to match
358 PrevGauge - Start node, start from list head if NULL
359
360 Returns:
361
362 Return pointer to the node found, NULL if not found.
363
364 --*/
365 {
366 EFI_PERF_DATA_LIST *Node;
367 EFI_PERF_DATA_LIST *Temp;
368 EFI_PERF_DATA_LIST *Temp2;
369 LIST_ENTRY *CurrentLink;
370 EFI_GUID NullGuid = EFI_NULL_GUID;
371
372 Node = NULL;
373 Temp = NULL;
374 Temp2 = NULL;
375
376 if (PrevGauge == NULL) {
377 CurrentLink = mPerfDataHead.ForwardLink;
378 } else {
379 Temp2 = GAUGE_DATA_FROM_GAUGE (PrevGauge);
380 CurrentLink = (Temp2->Link).ForwardLink;
381 }
382
383 while (CurrentLink && CurrentLink != &mPerfDataHead) {
384 Node = GAUGE_DATA_FROM_LINK (CurrentLink);
385
386 if (Handle == 0 && Token == NULL && Host == NULL && GuidName == NULL) {
387 return Node;
388 }
389
390 if (Handle != (Node->GaugeData).Handle) {
391 CurrentLink = CurrentLink->ForwardLink;
392 continue;
393 }
394
395 if (GuidName == NULL && !CompareGuid (&((Node->GaugeData).GuidName), &NullGuid)) {
396 CurrentLink = CurrentLink->ForwardLink;
397 continue;
398 }
399
400 if (GuidName && !CompareGuid (&((Node->GaugeData).GuidName), GuidName)) {
401 CurrentLink = CurrentLink->ForwardLink;
402 continue;
403 }
404
405 if (Token == NULL && StrCmp (Node->GaugeData.Token, L"")) {
406 CurrentLink = CurrentLink->ForwardLink;
407 continue;
408 }
409
410 if (Token && StrCmp (Node->GaugeData.Token, Token)) {
411 CurrentLink = CurrentLink->ForwardLink;
412 continue;
413 }
414
415 if (Host == NULL && StrCmp (Node->GaugeData.Host, L"")) {
416 CurrentLink = CurrentLink->ForwardLink;
417 continue;
418 }
419
420 if (Host && StrCmp (Node->GaugeData.Host, Host)) {
421 CurrentLink = CurrentLink->ForwardLink;
422 continue;
423 }
424
425 Temp = Node;
426 break;
427 }
428
429 return Temp;
430 }
431
432
433 EFI_STATUS
434 GetPeiPerformance (
435 IN EFI_HANDLE ImageHandle,
436 IN EFI_SYSTEM_TABLE *SystemTable,
437 IN UINT64 Ticker
438 )
439 /*++
440
441 Routine Description:
442
443 Transfer PEI performance data to gauge data node.
444
445 Arguments:
446
447 ImageHandle - Standard entry point parameter
448 SystemTable - Standard entry point parameter
449 Ticker - Start tick
450
451 Returns:
452
453 EFI_OUT_OF_RESOURCES - No enough resource to create data node.
454 EFI_SUCCESS - Transfer done successfully.
455
456 --*/
457 {
458 EFI_STATUS Status;
459 VOID *HobList;
460 EFI_HOB_GUID_TYPE *GuidHob;
461 EFI_HOB_GUID_DATA_PERFORMANCE_LOG *LogHob;
462 PEI_PERFORMANCE_MEASURE_LOG_ENTRY *LogEntry;
463 UINT32 Index;
464 EFI_PERF_DATA_LIST *Node;
465 UINT64 TimerValue;
466
467 Node = CreateDataNode (0, PEI_TOK, NULL);
468 if (!Node) {
469 return EFI_OUT_OF_RESOURCES;
470 }
471
472 if (Ticker != 0) {
473 TimerValue = Ticker;
474 } else {
475 InternalGetTimerValue (&TimerValue);
476 }
477 (Node->GaugeData).EndTick = TimerValue;
478
479 InsertTailList (&mPerfDataHead, &(Node->Link));
480
481 Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
482 ASSERT_EFI_ERROR (Status);
483
484 do {
485 GuidHob = (EFI_HOB_GUID_TYPE *)GlueGetNextGuidHob (&gEfiPeiPerformanceHobGuid, &HobList);
486 LogHob = (EFI_HOB_GUID_DATA_PERFORMANCE_LOG *)GET_GUID_HOB_DATA (GuidHob);
487
488 for (Index = 0; Index < LogHob->NumberOfEntries; Index++) {
489 LogEntry = &(LogHob->Log[Index]);
490 Node = CreateDataNode (0, LogEntry->DescriptionString, NULL);
491 if (!Node) {
492 return EFI_OUT_OF_RESOURCES;
493 }
494 (Node->GaugeData).StartTick = LogEntry->StartTimeCount;
495
496 CopyMem (&(Node->GaugeData.GuidName), &LogEntry->Name, sizeof (EFI_GUID));
497
498 InsertTailList (&mPerfDataHead, &(Node->Link));
499
500 (Node->GaugeData).EndTick = LogEntry->StopTimeCount;
501 }
502 } while (!EFI_ERROR (Status));
503
504 return EFI_SUCCESS;
505 }
506
507
508 EFI_STATUS
509 EFIAPI
510 StartGauge (
511 IN EFI_PERFORMANCE_PROTOCOL *This,
512 IN EFI_HANDLE Handle,
513 IN UINT16 *Token,
514 IN UINT16 *Host,
515 IN UINT64 Ticker
516 )
517 /*++
518
519 Routine Description:
520
521 Create a guage data node and initialized it.
522
523 Arguments:
524
525 This - Calling context
526 Handle - Handle of gauge data
527 Token - Token of gauge data
528 Host - Host of gauge data
529 Ticker - Set gauge data's StartTick. If 0, StartTick is current timer.
530
531 Returns:
532
533 EFI_SUCCESS - Successfully create and initialized a guage data node.
534 EFI_OUT_OF_RESOURCES - No enough resource to create a guage data node.
535
536 --*/
537 {
538 EFI_PERFORMANCE_INSTANCE *PerfInstance;
539 EFI_PERF_DATA_LIST *Node;
540 UINT64 TimerValue;
541
542 TimerValue = 0;
543 PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
544
545 Node = CreateDataNode (Handle, Token, Host);
546 if (!Node) {
547 return EFI_OUT_OF_RESOURCES;
548 }
549
550 if (Ticker != 0) {
551 TimerValue = Ticker;
552 } else {
553 InternalGetTimerValue (&TimerValue);
554 }
555
556 Node->GaugeData.StartTick = TimerValue;
557
558 if (!StrCmp (Token, DXE_TOK)) {
559 PerfInstance->Phase = DXE_PHASE;
560 }
561
562 if (!StrCmp (Token, SHELL_TOK)) {
563 PerfInstance->Phase = SHELL_PHASE;
564 }
565
566 Node->GaugeData.Phase = PerfInstance->Phase;
567
568 InsertTailList (&mPerfDataHead, &(Node->Link));
569
570 return EFI_SUCCESS;
571 }
572
573
574 EFI_STATUS
575 EFIAPI
576 EndGauge (
577 IN EFI_PERFORMANCE_PROTOCOL *This,
578 IN EFI_HANDLE Handle,
579 IN UINT16 *Token,
580 IN UINT16 *Host,
581 IN UINT64 Ticker
582 )
583 /*++
584
585 Routine Description:
586
587 End all unfinished gauge data node that match specified handle, token and host.
588
589 Arguments:
590
591 This - Calling context
592 Handle - Handle to stop
593 Token - Token to stop
594 Host - Host to stop
595 Ticker - End tick, if 0 then get current timer
596
597 Returns:
598
599 EFI_NOT_FOUND - Node not found
600 EFI_SUCCESS - Gauge data node successfully ended.
601
602 --*/
603 {
604 EFI_PERFORMANCE_INSTANCE *PerfInstance;
605 EFI_PERF_DATA_LIST *Node;
606 UINT64 TimerValue;
607
608 TimerValue = 0;
609 PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
610
611 Node = GetDataNode (Handle, Token, Host, NULL, NULL);
612 if (!Node) {
613 return EFI_NOT_FOUND;
614 }
615
616 while (Node->GaugeData.EndTick != 0) {
617 Node = GetDataNode (Handle, Token, Host, NULL, &(Node->GaugeData));
618 if (!Node) {
619 return EFI_NOT_FOUND;
620 }
621 }
622
623 if (Ticker != 0) {
624 TimerValue = Ticker;
625 } else {
626 InternalGetTimerValue (&TimerValue);
627 }
628
629 Node->GaugeData.EndTick = TimerValue;
630
631 return EFI_SUCCESS;
632 }
633
634
635 EFI_GAUGE_DATA *
636 EFIAPI
637 GetGauge (
638 IN EFI_PERFORMANCE_PROTOCOL *This,
639 IN EFI_HANDLE Handle,
640 IN UINT16 *Token,
641 IN UINT16 *Host,
642 IN EFI_GAUGE_DATA *PrevGauge
643 )
644 /*++
645
646 Routine Description:
647 Get gauge.
648
649 Arguments:
650 This - A pointer to the EFI_PERFORMANCE_PROTOCOL.
651 Handle - A pointer of a efi handle.
652 Token - A pointer to the token.
653 Host - A pointer to the host.
654 PrevGauge - A pointer to the EFI_GAUGE_DATA structure.
655
656
657 Returns:
658 Status code.
659
660 --*/
661 {
662 EFI_PERFORMANCE_INSTANCE *PerfInstance;
663 EFI_PERF_DATA_LIST *Node;
664
665 PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
666
667 Node = GetDataNode (Handle, Token, Host, NULL, PrevGauge);
668 if (Node != NULL) {
669 return &(Node->GaugeData);
670 } else {
671 return NULL;
672 }
673 }
674
675
676 //
677 // Install Performance Protocol
678 //
679 // This is the support routine for PERF_ENABLE() which is called on
680 // an user's demand. This function isn't necessary to be called
681 // automatically.
682 //
683 EFI_STATUS
684 EFIAPI
685 InitializePerformanceInfrastructure (
686 IN EFI_HANDLE ImageHandle,
687 IN EFI_SYSTEM_TABLE *SystemTable,
688 IN UINT64 Ticker
689 )
690 /*++
691
692 Routine Description:
693
694 Install gEfiPerformanceProtocolGuid protocol and transfer PEI performance to gauge data nodes.
695
696 Arguments:
697
698 ImageHandle - Standard driver entry point parameter
699 SystemTable - Standard driver entry point parameter
700 Ticker - End tick for PEI performance
701
702 Returns:
703
704 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
705 EFI_SUCCESS - Protocol installed.
706
707 --*/
708 {
709 EFI_STATUS Status;
710 EFI_PERFORMANCE_INSTANCE *PerfInstance;
711
712 //
713 // Allocate a new image structure
714 //
715 PerfInstance = AllocateZeroPool (sizeof (EFI_PERFORMANCE_INSTANCE));
716 if (PerfInstance == NULL) {
717 return EFI_OUT_OF_RESOURCES;
718 }
719
720 PerfInstance->Signature = EFI_PERFORMANCE_SIGNATURE;
721 PerfInstance->Perf.StartGauge = StartGauge;
722 PerfInstance->Perf.EndGauge = EndGauge;
723 PerfInstance->Perf.GetGauge = GetGauge;
724
725 //
726 // Install the protocol interfaces
727 //
728 Status = gBS->InstallProtocolInterface (
729 &PerfInstance->Handle,
730 &gEfiPerformanceProtocolGuid,
731 EFI_NATIVE_INTERFACE,
732 &PerfInstance->Perf
733 );
734
735 if (!EFI_ERROR (Status)) {
736 GetPeiPerformance (ImageHandle, SystemTable, Ticker);
737 }
738
739 return EFI_SUCCESS;
740 }
741
742
743 EFI_STATUS
744 EFIAPI
745 StartMeasure (
746 EFI_HANDLE Handle,
747 IN UINT16 *Token,
748 IN UINT16 *Host,
749 IN UINT64 Ticker
750 )
751 /*++
752
753 Routine Description:
754
755 Start to gauge on a specified handle, token and host, with Ticker as start tick.
756
757 Arguments:
758
759 Handle - Handle to measure
760 Token - Token to measure
761 Host - Host to measure
762 Ticker - Ticker as start tick
763
764 Returns:
765
766 Status code.
767
768 --*/
769 {
770 EFI_STATUS Status;
771 EFI_PERFORMANCE_PROTOCOL *Perf;
772
773 Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
774 if (EFI_ERROR (Status)) {
775 return Status;
776 }
777
778 return Perf->StartGauge (Perf, Handle, Token, Host, Ticker);
779
780 }
781
782
783 EFI_STATUS
784 EFIAPI
785 EndMeasure (
786 EFI_HANDLE Handle,
787 IN UINT16 *Token,
788 IN UINT16 *Host,
789 IN UINT64 Ticker
790 )
791 /*++
792
793 Routine Description:
794
795 End gauging on a specified handle, token and host, with Ticker as end tick.
796
797 Arguments:
798
799 Handle - Handle to stop
800 Token - Token to stop
801 Host - Host to stop
802 Ticker - Ticker as end tick
803
804 Returns:
805
806 Status code.
807
808 --*/
809 {
810 EFI_STATUS Status;
811 EFI_PERFORMANCE_PROTOCOL *Perf;
812
813 Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
814 if (Status != EFI_SUCCESS) {
815 return Status;
816 }
817
818 return (Perf->EndGauge( Perf, Handle, Token, Host, Ticker)) ;
819 }
820
821
822 EFI_STATUS
823 EFIAPI
824 UpdateMeasure (
825 EFI_HANDLE Handle,
826 IN UINT16 *Token,
827 IN UINT16 *Host,
828 EFI_HANDLE HandleNew,
829 IN UINT16 *TokenNew,
830 IN UINT16 *HostNew
831 )
832 /*++
833
834 Routine Description:
835 Update measure.
836
837 Arguments:
838 Handle - A pointer of an efi handle.
839 Token - A pointer to the token.
840 Host - A pointer to the host.
841 HandleNew - A pointer of an new efi handle.
842 TokenNew - A pointer to the new token.
843 HostNew - A pointer to the new host.
844
845 Returns:
846 Status code.
847
848 EFI_NOT_FOUND - The speicified gauge data node not found.
849
850 EFI_SUCCESS - Update successfully.
851
852 --*/
853 {
854 EFI_STATUS Status;
855 EFI_GAUGE_DATA *GaugeData;
856 EFI_PERFORMANCE_PROTOCOL *Perf;
857
858 Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
859 if (EFI_ERROR (Status)) {
860 return Status;
861 }
862
863 GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL);
864 if (!GaugeData) {
865 return EFI_NOT_FOUND;
866 }
867
868 GaugeData->Handle = HandleNew;
869 if (HostNew != NULL) {
870 StrCpy (GaugeData->Host, HostNew);
871 } else {
872 StrCpy (GaugeData->Host, L"");
873 }
874
875 if (TokenNew != NULL) {
876 StrCpy (GaugeData->Token, TokenNew);
877 } else {
878 StrCpy (GaugeData->Token, L"");
879 }
880
881 return EFI_SUCCESS;
882 }
883