/** @file\r
\r
- Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2014 - 2016, 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
\r
**/\r
\r
+#include <Base.h>\r
#include <Uefi.h>\r
#include <PiDxe.h>\r
#include <Library/BaseLib.h>\r
\r
#include <Guid/ZeroGuid.h>\r
#include <Guid/MemoryProfile.h>\r
+#include <Guid/PiSmmCommunicationRegionTable.h>\r
\r
CHAR16 *mActionString[] = {\r
L"Unknown",\r
UINT8 *CommBuffer;\r
EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo;\r
- SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *CommGetProfileData;\r
- UINT64 ProfileSize;\r
- PHYSICAL_ADDRESS ProfileBuffer;\r
+ SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData;\r
+ UINTN ProfileSize;\r
+ VOID *ProfileBuffer;\r
EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;\r
+ UINTN MinimalSizeNeeded;\r
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
+ UINT32 Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
+ VOID *Buffer;\r
+ UINTN Size;\r
+ UINTN Offset;\r
\r
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
- CommBuffer = AllocateZeroPool (CommSize);\r
- if (CommBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- Print (L"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize, Status);\r
+ MinimalSizeNeeded = sizeof (EFI_GUID) +\r
+ sizeof (UINTN) +\r
+ MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),\r
+ sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET));\r
+ MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT),\r
+ MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO),\r
+ MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO),\r
+ MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR),\r
+ MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY),\r
+ sizeof (MEMORY_PROFILE_MEMORY_RANGE))))));\r
+\r
+ Status = EfiGetSystemConfigurationTable (\r
+ &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+ (VOID **) &PiSmmCommunicationRegionTable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status));\r
return Status;\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 >= MinimalSizeNeeded) {\r
+ break;\r
+ }\r
+ }\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+ }\r
+ ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+ CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
\r
//\r
// Get Size\r
CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
if (EFI_ERROR (Status)) {\r
- FreePool (CommBuffer);\r
DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));\r
return Status;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
- ProfileSize = CommGetProfileInfo->ProfileSize;\r
+ ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize;\r
\r
//\r
// Get Data\r
//\r
- ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool ((UINTN) ProfileSize);\r
+ ProfileBuffer = AllocateZeroPool (ProfileSize);\r
if (ProfileBuffer == 0) {\r
- FreePool (CommBuffer);\r
Status = EFI_OUT_OF_RESOURCES;\r
- Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN) ProfileSize, Status);\r
+ Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status);\r
return Status;\r
}\r
\r
CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));\r
- CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
+ CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET);\r
\r
- CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
- CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA;\r
+ CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
+ CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET;\r
CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData);\r
CommGetProfileData->Header.ReturnStatus = (UINT64)-1;\r
- CommGetProfileData->ProfileSize = ProfileSize;\r
- CommGetProfileData->ProfileBuffer = ProfileBuffer;\r
\r
CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
- Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
- ASSERT_EFI_ERROR (Status);\r
+ Buffer = (UINT8 *) CommHeader + CommSize;\r
+ Size -= CommSize;\r
+\r
+ CommGetProfileData->ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) Buffer;\r
+ CommGetProfileData->ProfileOffset = 0;\r
+ while (CommGetProfileData->ProfileOffset < ProfileSize) {\r
+ Offset = (UINTN) CommGetProfileData->ProfileOffset;\r
+ if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) {\r
+ CommGetProfileData->ProfileSize = (UINT64) Size;\r
+ } else {\r
+ CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset);\r
+ }\r
+ Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- if (CommGetProfileData->Header.ReturnStatus != 0) {\r
- FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
- FreePool (CommBuffer);\r
- Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
- return EFI_SUCCESS;\r
+ if (CommGetProfileData->Header.ReturnStatus != 0) {\r
+ FreePool (ProfileBuffer);\r
+ Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
+ return EFI_SUCCESS;\r
+ }\r
+ CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize);\r
}\r
\r
\r
- Print (L"SmramProfileSize - 0x%x\n", CommGetProfileData->ProfileSize);\r
+ Print (L"SmramProfileSize - 0x%x\n", ProfileSize);\r
Print (L"======= SmramProfile begin =======\n");\r
- DumpMemoryProfile (CommGetProfileData->ProfileBuffer, CommGetProfileData->ProfileSize);\r
+ DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize);\r
Print (L"======= SmramProfile end =======\n\n\n");\r
\r
- FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
- FreePool (CommBuffer);\r
+ FreePool (ProfileBuffer);\r
\r
return EFI_SUCCESS;\r
}\r