Home | History | Annotate | Download | only in PeiLib
      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