1 /*++ 2 3 Copyright (c) 2004 - 2008, 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 Module Name: 13 14 Perf.c 15 16 Abstract: 17 18 Support for performance primitives. 19 20 --*/ 21 22 #include "Tiano.h" 23 #include "Pei.h" 24 #include "PeiLib.h" 25 #include "PeiHob.h" 26 27 #include EFI_GUID_DEFINITION (PeiPerformanceHob) 28 29 // 30 // Perfomance HOB data definitions 31 // 32 33 #define MAX_PEI_PERF_LOG_ENTRIES 28 34 35 // 36 // Prototype functions 37 // 38 EFI_STATUS 39 GetTimerValue ( 40 OUT UINT64 *TimerValue 41 ); 42 43 44 VOID 45 EFIAPI 46 PeiPerfMeasure ( 47 EFI_PEI_SERVICES **PeiServices, 48 IN UINT16 *Token, 49 IN EFI_FFS_FILE_HEADER *FileHeader, 50 IN BOOLEAN EntryExit, 51 IN UINT64 Value 52 ) 53 /*++ 54 55 Routine Description: 56 57 Log a timestamp count. 58 59 Arguments: 60 61 PeiServices - Pointer to the PEI Core Services table 62 63 Token - Pointer to Token Name 64 65 FileHeader - Pointer to the file header 66 67 EntryExit - Indicates start or stop measurement 68 69 Value - The start time or the stop time 70 71 Returns: 72 73 --*/ 74 { 75 EFI_STATUS Status; 76 EFI_HOB_GUID_TYPE *Hob; 77 EFI_HOB_GUID_DATA_PERFORMANCE_LOG *PerfHobData; 78 PEI_PERFORMANCE_MEASURE_LOG_ENTRY *Log; 79 EFI_PEI_PPI_DESCRIPTOR *PerfHobDescriptor; 80 UINT64 TimeCount; 81 INTN Index; 82 UINTN Index2; 83 EFI_GUID *Guid; 84 EFI_GUID *CheckGuid; 85 86 TimeCount = 0; 87 // 88 // Get the END time as early as possible to make it more accurate. 89 // 90 if (EntryExit) { 91 GetTimerValue (&TimeCount); 92 } 93 94 // 95 // Locate the Pei Performance Log Hob. 96 // 97 Status = (*PeiServices)->LocatePpi ( 98 PeiServices, 99 &gEfiPeiPerformanceHobGuid, 100 0, 101 &PerfHobDescriptor, 102 NULL 103 ); 104 105 // 106 // If the Performance Hob was not found, build and install one. 107 // 108 if (EFI_ERROR(Status)) { 109 Status = PeiBuildHobGuid ( 110 PeiServices, 111 &gEfiPeiPerformanceHobGuid, 112 (sizeof(EFI_HOB_GUID_DATA_PERFORMANCE_LOG) + 113 ((MAX_PEI_PERF_LOG_ENTRIES-1) * 114 sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY)) + 115 sizeof(EFI_PEI_PPI_DESCRIPTOR) 116 ), 117 (VOID **) &Hob 118 ); 119 ASSERT_PEI_ERROR((CONST EFI_PEI_SERVICES **) PeiServices, Status); 120 121 PerfHobData = (EFI_HOB_GUID_DATA_PERFORMANCE_LOG *)(Hob+1); 122 PerfHobData->NumberOfEntries = 0; 123 124 PerfHobDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)((UINT8 *)(PerfHobData+1) + 125 (sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY) * 126 (MAX_PEI_PERF_LOG_ENTRIES-1) 127 ) 128 ); 129 PerfHobDescriptor->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); 130 PerfHobDescriptor->Guid = &gEfiPeiPerformanceHobGuid; 131 PerfHobDescriptor->Ppi = NULL; 132 133 (*PeiServices)->InstallPpi ( 134 PeiServices, 135 PerfHobDescriptor 136 ); 137 } 138 139 PerfHobData = (EFI_HOB_GUID_DATA_PERFORMANCE_LOG *)(((UINT8 *)(PerfHobDescriptor)) - 140 ((sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY) * 141 (MAX_PEI_PERF_LOG_ENTRIES-1) 142 ) 143 + sizeof(EFI_HOB_GUID_DATA_PERFORMANCE_LOG) 144 ) 145 ); 146 147 if (PerfHobData->NumberOfEntries >= MAX_PEI_PERF_LOG_ENTRIES) { 148 return; 149 } 150 151 if (!EntryExit) { 152 Log = &(PerfHobData->Log[PerfHobData->NumberOfEntries]); 153 (*PeiServices)->SetMem (Log, sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY), 0); 154 155 // 156 // If not NULL pointer, copy the file name 157 // 158 if (FileHeader != NULL) { 159 Log->Name = FileHeader->Name; 160 } 161 162 // 163 // Copy the description string 164 // 165 (*PeiServices)->CopyMem ( 166 &(Log->DescriptionString), 167 Token, 168 (PEI_PERF_MAX_DESC_STRING-1) * sizeof(UINT16) 169 ); 170 171 // 172 // Get the start time as late as possible to make it more accurate. 173 // 174 GetTimerValue (&TimeCount); 175 176 // 177 // Record the time stamp. 178 // 179 if (Value != 0) { 180 Log->StartTimeCount = Value; 181 } else { 182 Log->StartTimeCount = TimeCount; 183 } 184 Log->StopTimeCount = 0; 185 186 // 187 // Increment the number of valid log entries. 188 // 189 PerfHobData->NumberOfEntries++; 190 191 } else { 192 193 for (Index = PerfHobData->NumberOfEntries-1; Index >= 0; Index--) { 194 Log = NULL; 195 for (Index2 = 0; Index2 < PEI_PERF_MAX_DESC_STRING; Index2++) { 196 if (PerfHobData->Log[Index].DescriptionString[Index2] == 0) { 197 Log = &(PerfHobData->Log[Index]); 198 break; 199 } 200 if (PerfHobData->Log[Index].DescriptionString[Index2] != 201 Token[Index2]) { 202 break; 203 } 204 } 205 if (Log != NULL) { 206 if (FileHeader != NULL) { 207 Guid = &(Log->Name); 208 CheckGuid = &(FileHeader->Name); 209 if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) && 210 (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) && 211 (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) && 212 (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) { 213 if (Value != 0) { 214 Log->StopTimeCount = Value; 215 } else { 216 Log->StopTimeCount = TimeCount; 217 } 218 break; 219 } 220 } else { 221 if (Value != 0) { 222 Log->StopTimeCount = Value; 223 } else { 224 Log->StopTimeCount = TimeCount; 225 } 226 break; 227 } 228 } 229 } 230 231 } 232 233 return; 234 } 235