Files
system76-edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.c
ajfish 2ce311322c Removed cross references from PciCf8Lib and PciExpressLib class to PciLib class.
Added PeCoffLoaderGetMachineType to the PeCoffGetEntryPointLibrary Class. Document to be updated.

Added the PeCoffLoaderImageReadFromMemory() and PeCoffLoaderRelocateImageForRuntime () to the PcCoffLib. 

Updated EfiImage.h and removed EFI_IMAGE_OPTIONAL_HEADER and EFI_IMAGE_NT_HEADERS as they were replaced with checking the MachineType.

PeCoffLib – Added checks for MachineType so the PeCoff lib can load any PE32 or PE32+ image. The relocations are still limited to IA32, X64, IPF, and EBC. I also added a re-relocator function to remove PeLoader Code from Runtime Lib. Even though there is only one instance of the re-relocator I wanted to get all the PeCoff loader code together.

Replaced DEBUG_CODE() macro with DEBUG_CODE_START() and DEBUG_CODE_END() so you can debug through the DEBUG_CODE() macros. Also removed PE/COFF code and replaced with library usage.

I also updated the IO Instrinsic lib to use _ReadWriteBarrior() to help with sync problems

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1103 6f19259b-4bc3-4df7-8a09-765794883524
2006-07-26 15:23:35 +00:00

399 lines
9.4 KiB
C

/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Performance.c
Abstract:
This file include the file which can help to get the system
performance, all the function will only include if the performance
switch is set.
--*/
#include "Performance.h"
VOID
ClearDebugRegisters (
VOID
)
{
//
// BugBug: We should not need to do this. We need to root cause this bug!!!!
//
AsmWriteDr0 (0);
AsmWriteDr1 (0);
}
STATIC
VOID
GetShortPdbFileName (
CHAR8 *PdbFileName,
CHAR8 *GaugeString
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
UINTN Index;
UINTN Index1;
UINTN StartIndex;
UINTN EndIndex;
if (PdbFileName == NULL) {
AsciiStrCpy (GaugeString, " ");
} else {
StartIndex = 0;
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
;
for (Index = 0; PdbFileName[Index] != 0; Index++) {
if (PdbFileName[Index] == '\\') {
StartIndex = Index + 1;
}
if (PdbFileName[Index] == '.') {
EndIndex = Index;
}
}
Index1 = 0;
for (Index = StartIndex; Index < EndIndex; Index++) {
GaugeString[Index1] = PdbFileName[Index];
Index1++;
if (Index1 == PERF_TOKEN_LENGTH - 1) {
break;
}
}
GaugeString[Index1] = 0;
}
return ;
}
STATIC
CHAR8 *
GetPdbPath (
VOID *ImageBase
)
/*++
Routine Description:
Located PDB path name in PE image
Arguments:
ImageBase - base of PE to search
Returns:
Pointer into image at offset of PDB file name if PDB file name is found,
Otherwise a pointer to an empty string.
--*/
{
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = ImageBase;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
PeCoffLoaderGetImageInfo (&ImageContext);
return ImageContext.PdbPointer;
}
STATIC
VOID
GetNameFromHandle (
IN EFI_HANDLE Handle,
OUT CHAR8 *GaugeString
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *Image;
CHAR8 *PdbFileName;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
AsciiStrCpy (GaugeString, " ");
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageProtocolGuid,
&Image
);
if (EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
Handle,
&gEfiDriverBindingProtocolGuid,
(VOID **) &DriverBinding,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
DriverBinding->ImageHandle,
&gEfiLoadedImageProtocolGuid,
&Image
);
}
PdbFileName = GetPdbPath (Image->ImageBase);
if (PdbFileName != NULL) {
GetShortPdbFileName (PdbFileName, GaugeString);
}
return ;
}
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_PHYSICAL_ADDRESS mAcpiLowMemoryBase;
UINT32 mAcpiLowMemoryLength;
UINT32 LimitCount;
PERF_HEADER mPerfHeader;
PERF_DATA mPerfData;
EFI_HANDLE *Handles;
UINTN NoHandles;
CHAR8 GaugeString[PERF_TOKEN_LENGTH];
UINT8 *Ptr;
UINT32 mIndex;
UINT64 Ticker;
UINT64 Freq;
UINT32 Duration;
UINT64 CurrentTicker;
UINT64 TimerPeriod;
UINTN LogEntryKey;
CONST VOID *Handle;
CONST CHAR8 *Token;
CONST CHAR8 *Module;
UINT64 StartTicker;
UINT64 EndTicker;
//
// Retrive time stamp count as early as possilbe
//
Ticker = AsmReadTsc ();
//
// Allocate a block of memory that contain performance data to OS
//
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiACPIReclaimMemory,
4,
&mAcpiLowMemoryBase
);
if (EFI_ERROR (Status)) {
return ;
}
mAcpiLowMemoryLength = 0x1000;
Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
LimitCount = (mAcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
//
// Initialize performance data structure
//
ZeroMem (&mPerfHeader, sizeof (PERF_HEADER));
//
// Get CPU frequency
//
Status = gBS->LocateProtocol (
&gEfiCpuArchProtocolGuid,
NULL,
&Cpu
);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 1);
return ;
}
//
// Get Cpu Frequency
//
Status = Cpu->GetTimerValue (Cpu, 0, &(CurrentTicker), &TimerPeriod);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 1);
return ;
}
Freq = DivU64x32 (1000000000000, (UINTN) TimerPeriod);
mPerfHeader.CpuFreq = Freq;
//
// Record BDS raw performance data
//
mPerfHeader.BDSRaw = Ticker;
//
// Put Detailed performance data into memory
//
Handles = NULL;
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&NoHandles,
&Handles
);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 1);
return ;
}
//
// Get DXE drivers performance
//
for (mIndex = 0; mIndex < NoHandles; mIndex++) {
Ticker = 0;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if ((Handle == Handles[mIndex]) && (StartTicker < EndTicker)) {
Ticker += (EndTicker - StartTicker);
}
}
Duration = (UINT32) DivU64x32 (
Ticker,
(UINT32) Freq
);
if (Duration > 0) {
ZeroMem (&mPerfData, sizeof (PERF_DATA));
GetNameFromHandle (Handles[mIndex], GaugeString);
AsciiStrCpy (mPerfData.Token, GaugeString);
mPerfData.Duration = Duration;
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
gBS->FreePool (Handles);
//
// Get inserted performance data
//
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if ((Handle == NULL) && (StartTicker <= EndTicker)) {
ZeroMem (&mPerfData, sizeof (PERF_DATA));
AsciiStrnCpy (mPerfData.Token, Token, DXE_PERFORMANCE_STRING_SIZE);
mPerfData.Duration = (UINT32) DivU64x32 (
EndTicker - StartTicker,
(UINT32) Freq
);
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
Done:
ClearDebugRegisters ();
mPerfHeader.Signiture = 0x66726550;
//
// Put performance data to memory
//
CopyMem (
(UINT32 *) (UINT32) mAcpiLowMemoryBase,
&mPerfHeader,
sizeof (PERF_HEADER)
);
gRT->SetVariable (
L"PerfDataMemAddr",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof (UINT32),
(VOID *) &mAcpiLowMemoryBase
);
return ;
}