performance, all the function will only include if the performance\r
switch is set.\r
\r
-Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
UINTN EndIndex;\r
\r
if (PdbFileName == NULL) {\r
- AsciiStrCpy (GaugeString, " ");\r
+ AsciiStrCpyS (GaugeString, PERF_TOKEN_LENGTH, " ");\r
} else {\r
StartIndex = 0;\r
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
CHAR8 *PdbFileName;\r
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
\r
- AsciiStrCpy (GaugeString, " ");\r
+ AsciiStrCpyS (GaugeString, PERF_TOKEN_LENGTH, " ");\r
\r
//\r
// Get handle name from image protocol\r
\r
/**\r
\r
- Allocates a block of memory and writes performance data of booting into it.\r
- OS can processing these record.\r
- \r
+ Writes performance data of booting into the allocated memory.\r
+ OS can process these records.\r
+\r
+ @param Event The triggered event.\r
+ @param Context Context for this event.\r
+\r
**/\r
VOID\r
+EFIAPI\r
WriteBootToOsPerformanceData (\r
- VOID\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
EFI_STATUS Status;\r
- UINT32 AcpiLowMemoryLength;\r
UINT32 LimitCount;\r
EFI_HANDLE *Handles;\r
UINTN NoHandles;\r
UINT64 StartValue;\r
UINT64 EndValue;\r
BOOLEAN CountUp;\r
+ UINTN EntryIndex;\r
+ UINTN NumPerfEntries;\r
+ //\r
+ // List of flags indicating PerfEntry contains DXE handle\r
+ //\r
+ BOOLEAN *PerfEntriesAsDxeHandle;\r
+ UINTN VarSize;\r
+\r
+ //\r
+ // Record the performance data for End of BDS\r
+ //\r
+ PERF_END(NULL, "BDS", NULL, 0);\r
\r
//\r
// Retrieve time stamp count as early as possible\r
CountUp = FALSE;\r
}\r
\r
+ if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {\r
+ VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
+ Status = gRT->GetVariable (\r
+ L"PerfDataMemAddr",\r
+ &gPerformanceProtocolGuid,\r
+ NULL,\r
+ &VarSize,\r
+ &mAcpiLowMemoryBase\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Fail to get the variable, return.\r
+ //\r
+ return;\r
+ }\r
+ }\r
+\r
//\r
// Put Detailed performance data into memory\r
//\r
return ;\r
}\r
\r
-\r
- AcpiLowMemoryLength = 0x4000;\r
- if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {\r
- //\r
- // Allocate a block of memory that contain performance data to OS\r
- //\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiReservedMemoryType,\r
- EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),\r
- &mAcpiLowMemoryBase\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Handles);\r
- return ;\r
- }\r
- }\r
-\r
-\r
Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));\r
- LimitCount = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
-\r
+ LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
\r
+ NumPerfEntries = 0;\r
+ LogEntryKey = 0;\r
+ while ((LogEntryKey = GetPerformanceMeasurement (\r
+ LogEntryKey,\r
+ &Handle,\r
+ &Token,\r
+ &Module,\r
+ &StartTicker,\r
+ &EndTicker)) != 0) {\r
+ NumPerfEntries++;\r
+ }\r
+ PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN));\r
+ ASSERT (PerfEntriesAsDxeHandle != NULL);\r
\r
//\r
// Get DXE drivers performance\r
for (Index = 0; Index < NoHandles; Index++) {\r
Ticker = 0;\r
LogEntryKey = 0;\r
+ EntryIndex = 0;\r
while ((LogEntryKey = GetPerformanceMeasurement (\r
LogEntryKey,\r
&Handle,\r
&Module,\r
&StartTicker,\r
&EndTicker)) != 0) {\r
+ if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) {\r
+ PerfEntriesAsDxeHandle[EntryIndex] = TRUE;\r
+ }\r
+ EntryIndex++;\r
if ((Handle == Handles[Index]) && (EndTicker != 0)) {\r
+ if (StartTicker == 1) {\r
+ StartTicker = StartValue;\r
+ }\r
+ if (EndTicker == 1) {\r
+ EndTicker = StartValue;\r
+ }\r
Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
}\r
}\r
\r
GetNameFromHandle (Handles[Index], GaugeString);\r
\r
- AsciiStrCpy (mPerfData.Token, GaugeString);\r
+ AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);\r
mPerfData.Duration = Duration;\r
\r
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
}\r
}\r
\r
- FreePool (Handles);\r
-\r
//\r
// Get inserted performance data\r
//\r
LogEntryKey = 0;\r
+ EntryIndex = 0;\r
while ((LogEntryKey = GetPerformanceMeasurement (\r
LogEntryKey,\r
&Handle,\r
&Module,\r
&StartTicker,\r
&EndTicker)) != 0) {\r
- if (Handle == NULL && EndTicker != 0) {\r
+ if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) {\r
\r
ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
\r
- AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);\r
+ AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);\r
+ if (StartTicker == 1) {\r
+ StartTicker = StartValue;\r
+ }\r
+ if (EndTicker == 1) {\r
+ EndTicker = StartValue;\r
+ }\r
Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
\r
mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
goto Done;\r
}\r
}\r
+ EntryIndex++;\r
}\r
\r
Done:\r
\r
+ FreePool (Handles);\r
+ FreePool (PerfEntriesAsDxeHandle);\r
+\r
mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;\r
\r
//\r
sizeof (PERF_HEADER)\r
);\r
\r
- gRT->SetVariable (\r
- L"PerfDataMemAddr",\r
- &gPerformanceProtocolGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- sizeof (EFI_PHYSICAL_ADDRESS),\r
- &mAcpiLowMemoryBase\r
- );\r
-\r
return ;\r
}\r