perf.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 841 行 · 第 1/2 页

C
841
字号
  Ticker  - Set gauge data's StartTick. If 0, StartTick is current timer.

Returns:

  EFI_SUCCESS     - Successfully create and initialized a guage data node.
  EFI_OUT_OF_RESOURCES  - No enough resource to create a guage data node.

--*/
{
  EFI_PERFORMANCE_INSTANCE  *PerfInstance;
  EFI_PERF_DATA_LIST        *Node;
  UINT64                    TimerValue;

  TimerValue    = 0;
  PerfInstance  = EFI_PERFORMANCE_FROM_THIS (This);

  Node          = CreateDataNode (Handle, Token, Host);
  if (!Node) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Ticker != 0) {
    TimerValue = Ticker;
  } else {
    GetTimerValue (&TimerValue);
  }

  Node->GaugeData.StartTick = TimerValue;

  if (!EfiStrCmp (Token, DXE_TOK)) {
    PerfInstance->Phase = DXE_PHASE;
  }

  if (!EfiStrCmp (Token, SHELL_TOK)) {
    PerfInstance->Phase = SHELL_PHASE;
  }

  Node->GaugeData.Phase = PerfInstance->Phase;

  InsertTailList (&mPerfDataHead, &(Node->Link));

  return EFI_SUCCESS;
}


EFI_STATUS
EFIAPI
EndGauge (
  IN EFI_PERFORMANCE_PROTOCOL         *This,
  IN EFI_HANDLE                       Handle,
  IN UINT16                           *Token,
  IN UINT16                           *Host,
  IN UINT64                           Ticker
  )
/*++

Routine Description:

  End all unfinished gauge data node that match specified handle, token and host.

Arguments:

  This    - Calling context
  Handle  - Handle to stop
  Token   - Token to stop
  Host    - Host to stop
  Ticker  - End tick, if 0 then get current timer

Returns:

  EFI_NOT_FOUND - Node not found
  EFI_SUCCESS - Gauge data node successfully ended.

--*/
{
  EFI_PERFORMANCE_INSTANCE  *PerfInstance;
  EFI_PERF_DATA_LIST        *Node;
  UINT64                    TimerValue;

  TimerValue    = 0;
  PerfInstance  = EFI_PERFORMANCE_FROM_THIS (This);

  Node          = GetDataNode (Handle, Token, Host, NULL, NULL);
  if (!Node) {
    return EFI_NOT_FOUND;
  }

  while (Node->GaugeData.EndTick != 0) {
    Node = GetDataNode (Handle, Token, Host, NULL, &(Node->GaugeData));
    if (!Node) {
      return EFI_NOT_FOUND;
    }
  }

  if (Ticker != 0) {
    TimerValue = Ticker;
  } else {
    GetTimerValue (&TimerValue);
  }

  Node->GaugeData.EndTick = TimerValue;

  return EFI_SUCCESS;
}


EFI_GAUGE_DATA *
EFIAPI
GetGauge (
  IN EFI_PERFORMANCE_PROTOCOL         *This,
  IN EFI_HANDLE                       Handle,
  IN UINT16                           *Token,
  IN UINT16                           *Host,
  IN EFI_GAUGE_DATA                   *PrevGauge
  )
/*++

Routine Description:
  Get gauge.

Arguments:
  This        - A pointer to the EFI_PERFORMANCE_PROTOCOL.
  Handle      - A pointer of a efi handle.
  Token       - A pointer to the token.
  Host        - A pointer to the host.
  PrevGauge   - A pointer to the EFI_GAUGE_DATA structure.


Returns:
  Status code.

--*/
{
  EFI_PERFORMANCE_INSTANCE  *PerfInstance;
  EFI_PERF_DATA_LIST        *Node;

  PerfInstance  = EFI_PERFORMANCE_FROM_THIS (This);

  Node          = GetDataNode (Handle, Token, Host, NULL, PrevGauge);
  if (Node != NULL) {
    return &(Node->GaugeData);
  } else {
    return NULL;
  }
}

//
// Driver entry point
//
EFI_STATUS
InitializePerformanceInfrastructure (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable,
  IN UINT64               Ticker
  )
/*++

Routine Description:

  Install gEfiPerformanceProtocolGuid protocol and transfer PEI performance to gauge data nodes.

Arguments:

  ImageHandle - Standard driver entry point parameter
  SystemTable - Standard driver entry point parameter
  Ticker      - End tick for PEI performance

Returns:

  EFI_OUT_OF_RESOURCES - No enough buffer to allocate
  EFI_SUCCESS - Protocol installed.

--*/
{
  EFI_STATUS                Status;
  EFI_PERFORMANCE_INSTANCE  *PerfInstance;

  //
  // Allocate a new image structure
  //
  PerfInstance = EfiLibAllocateZeroPool (sizeof (EFI_PERFORMANCE_INSTANCE));
  if (PerfInstance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  PerfInstance->Signature       = EFI_PERFORMANCE_SIGNATURE;
  PerfInstance->Perf.StartGauge = StartGauge;
  PerfInstance->Perf.EndGauge   = EndGauge;
  PerfInstance->Perf.GetGauge   = GetGauge;

  //
  // Install the protocol interfaces
  //
  Status = gBS->InstallProtocolInterface (
                  &PerfInstance->Handle,
                  &gEfiPerformanceProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &PerfInstance->Perf
                  );

  if (!EFI_ERROR (Status)) {
    GetPeiPerformance (ImageHandle, SystemTable, Ticker);
  }

  return EFI_SUCCESS;
}


EFI_STATUS
StartMeasure (
  EFI_HANDLE          Handle,
  IN UINT16           *Token,
  IN UINT16           *Host,
  IN UINT64           Ticker
  )
/*++

Routine Description:

  Start to gauge on a specified handle, token and host, with Ticker as start tick.

Arguments:

  Handle  - Handle to measure
  Token   - Token to measure
  Host    - Host to measure
  Ticker  - Ticker as start tick

Returns:

  Status code.

--*/
{
  EFI_STATUS                Status;
  EFI_PERFORMANCE_PROTOCOL  *Perf;

  Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Perf->StartGauge (Perf, Handle, Token, Host, Ticker);

}


EFI_STATUS
EndMeasure (
  EFI_HANDLE          Handle,
  IN UINT16           *Token,
  IN UINT16           *Host,
  IN UINT64           Ticker
  )
/*++

Routine Description:

  End gauging on a specified handle, token and host, with Ticker as end tick.

Arguments:

  Handle  - Handle to stop
  Token   - Token to stop
  Host    - Host to stop
  Ticker  - Ticker as end tick

Returns:

  Status code.

--*/
{
  EFI_STATUS                Status;
  EFI_PERFORMANCE_PROTOCOL  *Perf;

  Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
  if (Status != EFI_SUCCESS) {
    return Status;
  }

  return (Perf->EndGauge( Perf, Handle, Token, Host, Ticker)) ;
}


EFI_STATUS
UpdateMeasure (
  EFI_HANDLE         Handle,
  IN UINT16          *Token,
  IN UINT16          *Host,
  EFI_HANDLE         HandleNew,
  IN UINT16          *TokenNew,
  IN UINT16          *HostNew
  )
/*++

Routine Description:
  Update measure.

Arguments:
  Handle      - A pointer of an efi handle.
  Token       - A pointer to the token.
  Host        - A pointer to the host.
  HandleNew   - A pointer of an new efi handle.
  TokenNew    - A pointer to the new token.
  HostNew     - A pointer to the new host.

Returns:
  Status code.

  EFI_NOT_FOUND       - The speicified gauge data node not found.
  
  EFI_SUCCESS         - Update successfully.

--*/
{
  EFI_STATUS                Status;
  EFI_GAUGE_DATA            *GaugeData;
  EFI_PERFORMANCE_PROTOCOL  *Perf;

  Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL);
  if (!GaugeData) {
    return EFI_NOT_FOUND;
  }

  GaugeData->Handle = HandleNew;
  if (HostNew != NULL) {
    EfiStrCpy (GaugeData->Host, HostNew);
  } else {
    EfiStrCpy (GaugeData->Host, L"");
  }

  if (TokenNew != NULL) {
    EfiStrCpy (GaugeData->Token, TokenNew);
  } else {
    EfiStrCpy (GaugeData->Token, L"");
  }

  return EFI_SUCCESS;
}


EFI_STATUS
GetPeiPerformance (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable,
  IN UINT64               Ticker
  )
/*++

Routine Description:

  Transfer PEI performance data to gauge data node.

Arguments:

  ImageHandle - Standard entry point parameter
  SystemTable - Standard entry point parameter
  Ticker      - Start tick

Returns:

  EFI_OUT_OF_RESOURCES - No enough resource to create data node.
  EFI_SUCCESS - Transfer done successfully.

--*/
{
  EFI_STATUS                        Status;
  VOID                              *HobList;
  EFI_HOB_GUID_DATA_PERFORMANCE_LOG *LogHob;
  PEI_PERFORMANCE_MEASURE_LOG_ENTRY *LogEntry;
  UINT32                            Index;
  EFI_PERF_DATA_LIST                *Node;
  UINT64                            TimerValue;

  Node = CreateDataNode (0, PEI_TOK, NULL);
  if (!Node) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Ticker != 0) {
    TimerValue = Ticker;
  } else {
    GetTimerValue (&TimerValue);
  }
  (Node->GaugeData).EndTick = TimerValue;

  InsertTailList (&mPerfDataHead, &(Node->Link));

  EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
  do {
    Status = GetNextGuidHob (&HobList, &gEfiPeiPerformanceHobGuid, (VOID **) &LogHob, NULL);
    if (EFI_ERROR (Status)) {
      break;
    }

    for (Index = 0; Index < LogHob->NumberOfEntries; Index++) {
      LogEntry  = &(LogHob->Log[Index]);
      Node      = CreateDataNode (0, LogEntry->DescriptionString, NULL);
      if (!Node) {
        return EFI_OUT_OF_RESOURCES;
      }
      (Node->GaugeData).StartTick = LogEntry->StartTimeCount;

      EfiCopyMem (&(Node->GaugeData.GuidName), &LogEntry->Name, sizeof (EFI_GUID));

      InsertTailList (&mPerfDataHead, &(Node->Link));

      (Node->GaugeData).EndTick = LogEntry->StopTimeCount;
    }
  } while (!EFI_ERROR (Status));

  return EFI_SUCCESS;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?