\r
#include <Protocol/SmmCommunication.h>\r
\r
+#include <Guid/PiSmmCommunicationRegionTable.h>\r
+#include <Library/UefiLib.h>\r
+\r
#define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof (SMM_PERF_COMMUNICATE))\r
\r
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;\r
-UINT8 mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE];\r
+UINT8 *mSmmPerformanceBuffer;\r
GAUGE_DATA_ENTRY *mGaugeData = NULL;\r
UINTN mGaugeNumberOfEntries = 0;\r
GAUGE_DATA_ENTRY_EX *mGaugeDataEx = NULL;\r
IN UINTN LogEntryKey\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
- SMM_PERF_COMMUNICATE *SmmPerfCommData;\r
- UINTN CommSize;\r
- UINTN DataSize;\r
+ EFI_STATUS Status;\r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
+ SMM_PERF_COMMUNICATE *SmmPerfCommData;\r
+ UINTN CommSize;\r
+ UINTN DataSize;\r
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
+ UINT32 Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
+ UINT8 *Buffer;\r
+ UINTN Size;\r
+ UINTN NumberOfEntries;\r
+ UINTN EntriesGot;\r
\r
if (mNoSmmPerfHandler) {\r
//\r
return NULL;\r
}\r
\r
+ Status = EfiGetSystemConfigurationTable (\r
+ &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+ (VOID **) &PiSmmCommunicationRegionTable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+ ASSERT (PiSmmCommunicationRegionTable != NULL);\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);\r
+ Size = 0;\r
+ for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
+ if (Entry->Type == EfiConventionalMemory) {\r
+ Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);\r
+ if (Size >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY))) {\r
+ break;\r
+ }\r
+ }\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+ }\r
+ ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+ mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
+\r
//\r
// Initialize communicate buffer \r
//\r
}\r
\r
mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries;\r
- \r
+\r
+ Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
+ NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY);\r
DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
mGaugeData = AllocateZeroPool(DataSize);\r
ASSERT (mGaugeData != NULL);\r
- \r
+\r
//\r
// Get all SMM gauge data\r
// \r
SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
- SmmPerfCommData->LogEntryKey = 0;\r
- SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries;\r
- SmmPerfCommData->GaugeData = mGaugeData;\r
- Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
- if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
- FreePool (mGaugeData);\r
- mGaugeData = NULL;\r
- mGaugeNumberOfEntries = 0;\r
- }\r
+ SmmPerfCommData->GaugeData = (GAUGE_DATA_ENTRY *) Buffer;\r
+ EntriesGot = 0;\r
+ do {\r
+ SmmPerfCommData->LogEntryKey = EntriesGot;\r
+ if ((mGaugeNumberOfEntries - EntriesGot) >= NumberOfEntries) {\r
+ SmmPerfCommData->NumberOfEntries = NumberOfEntries;\r
+ } else {\r
+ SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries - EntriesGot;\r
+ }\r
+ Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+ if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
+ FreePool (mGaugeData);\r
+ mGaugeData = NULL;\r
+ mGaugeNumberOfEntries = 0;\r
+ return NULL;\r
+ } else {\r
+ CopyMem (&mGaugeData[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY));\r
+ }\r
+ EntriesGot += SmmPerfCommData->NumberOfEntries;\r
+ } while (EntriesGot < mGaugeNumberOfEntries);\r
\r
return mGaugeData;\r
}\r
IN UINTN LogEntryKey\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
- SMM_PERF_COMMUNICATE_EX *SmmPerfCommData;\r
- UINTN CommSize;\r
- UINTN DataSize;\r
+ EFI_STATUS Status;\r
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
+ SMM_PERF_COMMUNICATE_EX *SmmPerfCommData;\r
+ UINTN CommSize;\r
+ UINTN DataSize;\r
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
+ UINT32 Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
+ UINT8 *Buffer;\r
+ UINTN Size;\r
+ UINTN NumberOfEntries;\r
+ UINTN EntriesGot;\r
\r
if (mNoSmmPerfExHandler) {\r
//\r
return NULL;\r
}\r
\r
+ Status = EfiGetSystemConfigurationTable (\r
+ &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+ (VOID **) &PiSmmCommunicationRegionTable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+ ASSERT (PiSmmCommunicationRegionTable != NULL);\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);\r
+ Size = 0;\r
+ for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
+ if (Entry->Type == EfiConventionalMemory) {\r
+ Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);\r
+ if (Size >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY_EX))) {\r
+ break;\r
+ }\r
+ }\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+ }\r
+ ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+ mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
//\r
// Initialize communicate buffer \r
//\r
}\r
\r
mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries;\r
- \r
+\r
+ Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
+ NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY_EX);\r
DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);\r
mGaugeDataEx = AllocateZeroPool(DataSize);\r
ASSERT (mGaugeDataEx != NULL);\r
- \r
+\r
//\r
// Get all SMM gauge data\r
// \r
SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
- SmmPerfCommData->LogEntryKey = 0;\r
- SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx;\r
- SmmPerfCommData->GaugeDataEx = mGaugeDataEx;\r
- Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
- if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
- FreePool (mGaugeDataEx);\r
- mGaugeDataEx = NULL;\r
- mGaugeNumberOfEntriesEx = 0;\r
- }\r
- \r
+ SmmPerfCommData->GaugeDataEx = (GAUGE_DATA_ENTRY_EX *) Buffer;\r
+ EntriesGot = 0;\r
+ do {\r
+ SmmPerfCommData->LogEntryKey = EntriesGot;\r
+ if ((mGaugeNumberOfEntriesEx - EntriesGot) >= NumberOfEntries) {\r
+ SmmPerfCommData->NumberOfEntries = NumberOfEntries;\r
+ } else {\r
+ SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx - EntriesGot;\r
+ }\r
+ Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+ if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
+ FreePool (mGaugeDataEx);\r
+ mGaugeDataEx = NULL;\r
+ mGaugeNumberOfEntriesEx = 0;\r
+ return NULL;\r
+ } else {\r
+ CopyMem (&mGaugeDataEx[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY_EX));\r
+ }\r
+ EntriesGot += SmmPerfCommData->NumberOfEntries;\r
+ } while (EntriesGot < mGaugeNumberOfEntriesEx);\r
+\r
return mGaugeDataEx;\r
}\r
\r