Exemplo n.º 1
0
EFI_STATUS
GetTimerValue (
  OUT UINT64    *TimerValue
  )
{
  *TimerValue = EfiReadTsc ();
  return EFI_SUCCESS;
}
Exemplo n.º 2
0
EFI_STATUS
GetTimerValue (
  OUT UINT64    *TimerValue
  )
/*++

Routine Description:

  Set TimerValue with current tick.

Arguments:

  TimerValue  - Timer value to be set

Returns:

  EFI_SUCCESS - TimerValue is set.

--*/
{
  *TimerValue = EfiReadTsc ();
  return EFI_SUCCESS;
}
Exemplo n.º 3
0
EFI_STATUS
GetTimerValue (
  OUT UINT64    *TimerValue
  )
/*++

Routine Description:

  Get timer value.

Arguments:

  TimerValue  - Pointer to the returned timer value

Returns:

  EFI_SUCCESS - Successfully got timer value

--*/
{
  *TimerValue = EfiReadTsc ();
  return EFI_SUCCESS;
}
Exemplo n.º 4
0
VOID
WriteBootToOsPerformanceData (
  VOID
  )
/*++

Routine Description:

  Allocates a block of memory and writes performance data of booting to OS into it.

Arguments:

  None

Returns:

  None

--*/
{
  EFI_STATUS                Status;
  EFI_CPU_ARCH_PROTOCOL     *Cpu;
  EFI_PERFORMANCE_PROTOCOL  *DrvPerf;
  UINT32                    mAcpiLowMemoryLength;
  UINT32                    LimitCount;
  EFI_PERF_HEADER           mPerfHeader;
  EFI_PERF_DATA             mPerfData;
  EFI_GAUGE_DATA            *DumpData;
  EFI_HANDLE                *Handles;
  UINTN                     NoHandles;
  UINT8                     *Ptr;
  UINT8                     *PdbFileName;
  UINT32                    mIndex;
  UINT64                    Ticker;
  UINT64                    Freq;
  UINT32                    Duration;
  UINT64                    CurrentTicker;
  UINT64                    TimerPeriod;

  //
  // Retrive time stamp count as early as possilbe
  //
  Ticker = EfiReadTsc ();

  //
  // Get performance architecture protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiPerformanceProtocolGuid,
                  NULL,
                  &DrvPerf
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Get CPU frequency
  //
  Status = gBS->LocateProtocol (
                  &gEfiCpuArchProtocolGuid,
                  NULL,
                  &Cpu
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Get Cpu Frequency
  //
  Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Put Detailed performance data into memory
  //
  Handles = NULL;
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &NoHandles,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Allocate a block of memory that contain performance data to OS
  // if it is not allocated yet.
  //
  if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    EfiReservedMemoryType,
                    4,
                    &mAcpiLowMemoryBase
                    );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (Handles);
      return ;
    }
  }

  mAcpiLowMemoryLength  = EFI_PAGES_TO_SIZE(4);
  Ptr                   = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (EFI_PERF_HEADER));
  LimitCount            = (mAcpiLowMemoryLength - sizeof (EFI_PERF_HEADER)) / sizeof (EFI_PERF_DATA);

  //
  // Initialize performance data structure
  //
  EfiZeroMem (&mPerfHeader, sizeof (EFI_PERF_HEADER));

  Freq                = DivU64x32 (1000000000000, (UINTN) TimerPeriod, NULL);

  mPerfHeader.CpuFreq = Freq;

  //
  // Record BDS raw performance data
  //
  mPerfHeader.BDSRaw = Ticker;

  //
  // Get DXE drivers performance
  //
  for (mIndex = 0; mIndex < NoHandles; mIndex++) {

    Ticker = 0;
    PdbFileName = NULL;
    DumpData = DrvPerf->GetGauge (
                          DrvPerf,    // Context
                          NULL,       // Handle
                          NULL,       // Token
                          NULL,       // Host
                          NULL        // PrecGauge
                          );
    while (DumpData) {
      if (DumpData->Handle == Handles[mIndex]) {
      	PdbFileName = &(DumpData->PdbFileName[0]);
      	if (DumpData->StartTick < DumpData->EndTick) {
      	  Ticker += (DumpData->EndTick - DumpData->StartTick);
      	}
      }

      DumpData = DrvPerf->GetGauge (
                            DrvPerf,  // Context
                            NULL,     // Handle
                            NULL,     // Token
                            NULL,     // Host
                            DumpData  // PrecGauge
                            );
    }

    Duration = (UINT32) DivU64x32 (
                          Ticker,
                          (UINT32) Freq,
                          NULL
                          );

    if (Duration > 0) {
      EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA));

      if (PdbFileName != NULL) {
        EfiAsciiStrCpy (mPerfData.Token, PdbFileName);
      }
      mPerfData.Duration = Duration;

      EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA));
      Ptr += sizeof (EFI_PERF_DATA);

      mPerfHeader.Count++;
      if (mPerfHeader.Count == LimitCount) {
        goto Done;
      }
    }
  }

  gBS->FreePool (Handles);

  //
  // Get inserted performance data
  //
  DumpData = DrvPerf->GetGauge (
                        DrvPerf,      // Context
                        NULL,         // Handle
                        NULL,         // Token
                        NULL,         // Host
                        NULL          // PrecGauge
                        );
  while (DumpData) {
    if ((DumpData->Handle) || (DumpData->StartTick > DumpData->EndTick)) {
      DumpData = DrvPerf->GetGauge (
                            DrvPerf,  // Context
                            NULL,     // Handle
                            NULL,     // Token
                            NULL,     // Host
                            DumpData  // PrecGauge
                            );
      continue;
    }

    EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA));

    ConvertChar16ToChar8 ((UINT8 *) mPerfData.Token, DumpData->Token);
    mPerfData.Duration = (UINT32) DivU64x32 (
                                    DumpData->EndTick - DumpData->StartTick,
                                    (UINT32) Freq,
                                    NULL
                                    );

    EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA));
    Ptr += sizeof (EFI_PERF_DATA);

    mPerfHeader.Count++;
    if (mPerfHeader.Count == LimitCount) {
      goto Done;
    }

    DumpData = DrvPerf->GetGauge (
                          DrvPerf,    // Context
                          NULL,       // Handle
                          NULL,       // Token
                          NULL,       // Host
                          DumpData    // PrecGauge
                          );
  }

Done:

  mPerfHeader.Signiture = 0x66726550;

  //
  // Put performance data to memory
  //
  EfiCopyMem (
    (UINTN *) (UINTN) mAcpiLowMemoryBase,
    &mPerfHeader,
    sizeof (EFI_PERF_HEADER)
    );

  gRT->SetVariable (
        L"PerfDataMemAddr",
        &gEfiGenericVariableGuid,
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        sizeof (UINT32),
        (VOID *) &mAcpiLowMemoryBase
        );

  return ;
}
Exemplo n.º 5
0
EFI_STATUS
ExecElet (
  IN OUT EFI_NETWORK_TEST_FILE    *TestFile,
  IN CHAR16                       *TestNodeName
  )
/*++

Routine Description:

  Execute an application.

Arguments:

  TestFile      - Pointer to the EFI_EFI_NETWORK_TEST_FILE structure.
  TestNodeName  - Test node name string.

Returns:

  EFI_SUCCESS          - Operation succeeded.
  EFI_UNSUPPORTED      - Unsupported test file.
  EFI_OUT_OF_RESOURCES - Memory allocation failed.
  Others               - Some failure happened.
  
--*/
{
  EFI_STATUS                Status;
  UINTN                     ExitDataSize;
  CHAR16                    *ExitData;
  EFI_HANDLE                ImageHandle;
  EFI_DEVICE_PATH_PROTOCOL  *FileNode;
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  UINT64                    StartTick;
  UINT64                    StopTick;

  if ((TestFile->Type == EFI_NETWORK_TEST_FILE_APPLICATION) && (TestNodeName == NULL)) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_TRACE, L"in ExecElet:begin exe (%s)", TestFile->FileName));

    //
    // Add the file path to the device path
    //
    FileNode = FileDevicePath (NULL, TestFile->FileName);
    if (FileNode == NULL) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"in ExecElet:Create file device path - %r", EFI_OUT_OF_RESOURCES));
      return EFI_OUT_OF_RESOURCES;
    }

    FilePath = AppendDevicePath (gEasFT->DevicePath, FileNode);
    if (FilePath == NULL) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"in ExecElet:Append file device path - %r", EFI_OUT_OF_RESOURCES));
      BS->FreePool (FileNode);
      return EFI_OUT_OF_RESOURCES;
    }

    BS->FreePool (FileNode);

    //
    // Load the test file
    //
    Status = BS->LoadImage (
                  FALSE,
                  gEasFT->ImageHandle,
                  FilePath,
                  NULL,
                  0,
                  &ImageHandle
                  );
    if (EFI_ERROR (Status)) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"in ExecElet:Load image - %r", Status));
      BS->FreePool (FilePath);
      return Status;
    }

    BS->FreePool (FilePath);
    EFI_ENTS_STATUS ((L"in ExecElet: Finish Loading image file <%s>", TestFile->FileName));

    //
    // Verify the image is an application or not
    //
    Status = BS->HandleProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (void **)&LoadedImage
                  );
    if (EFI_ERROR (Status)) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"in ExecElet: HandleProtocol - %r", Status));
	  BS->UnloadImage(ImageHandle);
      return Status;
    }

    if (LoadedImage->ImageCodeType == EfiLoaderCode) {
      //
      // It is an application
      //
#ifdef EFIARM
      StartTick = 0;
#else 
      StartTick = EfiReadTsc ();
#endif
      Status = BS->StartImage (
                    ImageHandle,
                    &ExitDataSize,
                    &ExitData
                    );
#ifdef EFIARM
      StopTick = 0;
#else 
      StopTick = EfiReadTsc ();
#endif
      RecordExecTime (StartTick, StopTick);
      if (EFI_ERROR (Status)) {
        EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Error in ExecElet: Start image - %r\n", Status));
      }
    } else {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_WARNING, L"Unsupported test file"));
      Status = EFI_UNSUPPORTED;
    }
	BS->UnloadImage(ImageHandle);
	return Status;
  } else if ((TestFile->Type == EFI_NETWORK_TEST_FILE_DRIVER) && (TestNodeName != NULL)) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_TRACE, L"in ExecElet:begin exe (%s->%s)", TestFile->CmdName, TestNodeName));

    Status = ExecDriver (TestFile, TestNodeName);
    if (EFI_ERROR (Status)) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Error in ExecDriver: Status - %r\n", Status));
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Exemplo n.º 6
0
EFI_STATUS
ExecDriver (
  IN OUT EFI_NETWORK_TEST_FILE    *TestFile,
  IN CHAR16                       *TestNodeName
  )
/*++

Routine Description:

  Execute a driver.

Arguments:

  TestFile      - Pointer to the EFI_EFI_NETWORK_TEST_FILE structure.
  TestNodeName  - Test node name string.

Returns:

  EFI_SUCCESS          - Operation succeeded.
  EFI_OUT_OF_RESOURCES - Memory allocation failed.
  Others               - Some failure happened.

--*/
{
  EFI_ENTS_PROTOCOL *EntsProtocol;
  ENTS_INTERFACE    *EntsInterface;
  EFI_STATUS        Status;
  EFI_STATUS        TestStatus;
  RIVL_VARIABLE     *DelayTimeVariable;
  UINT64            StartTick;
  UINT64            StopTick;

  //
  // Find the EntsProtocol instance by name
  // and install the client instance by index
  //
  Status  = LocateEntsProtocol (TestFile->CmdName, &EntsProtocol);
  if (EFI_ERROR (Status)) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Error in LocateEntsProtocol: Status - %r\n", Status));
    return Status;
  }
  //
  // Find the EntsInterface by name
  //
  Status = LocateEntsInterface (EntsProtocol, TestNodeName, &EntsInterface);
  if (EFI_ERROR (Status)) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Error in LocateEntsInterface: Status - %r\n", Status));
    return Status;
  }
  //
  // Parse the argument list
  //
  Status = ParseArg (EntsInterface->ArgFieldList);
  if (EFI_ERROR (Status)) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Error in ParseArg: Status - %r\n", Status));
    return Status;
  }
  //
  // Find variable (DelayTime)
  //
  DelayTimeVariable = SearchRivlVariable (DELAY_TIME_NAME);
  if (DelayTimeVariable != NULL) {
    BS->Stall (*(UINTN *) DelayTimeVariable->Address);
  }
  //
  // Call the entry point
  //
#ifdef EFIARM
      StartTick = 0;
#else 
      StartTick = EfiReadTsc ();
#endif
  TestStatus  = EntsInterface->EntsInterfaceEntry (EntsProtocol->ClientInterface);
#ifdef EFIARM
      StopTick = 0;
#else 
      StopTick = EfiReadTsc ();
#endif
  RecordExecTime (StartTick, StopTick);

  if (EntsProtocol->RuntimeInfo != NULL) {
    (gEasFT->Cmd)->ComdRuntimeInfo = EntsStrDuplicate (EntsProtocol->RuntimeInfo);
    if ((gEasFT->Cmd)->ComdRuntimeInfo == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    (gEasFT->Cmd)->ComdRuntimeInfoSize = (StrLen (EntsProtocol->RuntimeInfo) + 1) * 2;
    BS->FreePool (EntsProtocol->RuntimeInfo);
	EntsProtocol->RuntimeInfo = NULL;
	EntsProtocol->RuntimeInfoSize = 0;
  }

  return EFI_SUCCESS;
}