/** Get and dump UEFI memory profile data. @return EFI_SUCCESS Get the memory profile data successfully. @return other Fail to get the memory profile data. **/ EFI_STATUS GetUefiMemoryProfileData ( VOID ) { EFI_STATUS Status; EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol; VOID *Data; UINT64 Size; Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status)); return Status; } Size = 0; Data = NULL; Status = ProfileProtocol->GetData ( ProfileProtocol, &Size, Data ); if (Status != EFI_BUFFER_TOO_SMALL) { Print (L"UefiMemoryProfile: GetData - %r\n", Status); return Status; } // // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool action. // Size = Size + sizeof (MEMORY_PROFILE_ALLOC_INFO); Data = AllocateZeroPool ((UINTN) Size); if (Data == NULL) { Status = EFI_OUT_OF_RESOURCES; Print (L"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size, Status); return Status; } Status = ProfileProtocol->GetData ( ProfileProtocol, &Size, Data ); if (EFI_ERROR (Status)) { FreePool (Data); Print (L"UefiMemoryProfile: GetData - %r\n", Status); return Status; } Print (L"UefiMemoryProfileSize - 0x%x\n", Size); Print (L"======= UefiMemoryProfile begin =======\n"); DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) Data, Size); Print (L"======= UefiMemoryProfile end =======\n\n\n"); FreePool (Data); return EFI_SUCCESS; }
/** Get and dump SMRAM profile data. @return EFI_SUCCESS Get the SMRAM profile data successfully. @return other Fail to get the SMRAM profile data. **/ EFI_STATUS GetSmramProfileData ( VOID ) { EFI_STATUS Status; UINTN CommSize; UINT8 *CommBuffer; EFI_SMM_COMMUNICATE_HEADER *CommHeader; SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo; SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData; UINTN ProfileSize; VOID *ProfileBuffer; EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; UINTN MinimalSizeNeeded; EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; UINT32 Index; EFI_MEMORY_DESCRIPTOR *Entry; VOID *Buffer; UINTN Size; UINTN Offset; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status)); return Status; } MinimalSizeNeeded = sizeof (EFI_GUID) + sizeof (UINTN) + MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO), sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)); MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT), MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO), MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO), MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR), MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY), sizeof (MEMORY_PROFILE_MEMORY_RANGE)))))); Status = EfiGetSystemConfigurationTable ( &gEdkiiPiSmmCommunicationRegionTableGuid, (VOID **) &PiSmmCommunicationRegionTable ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status)); return Status; } ASSERT (PiSmmCommunicationRegionTable != NULL); Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1); Size = 0; for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { if (Entry->Type == EfiConventionalMemory) { Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages); if (Size >= MinimalSizeNeeded) { break; } } Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize); } ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries); CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart; // // Get Size // CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO); CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO; CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo); CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1; CommGetProfileInfo->ProfileSize = 0; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status)); return Status; } if (CommGetProfileInfo->Header.ReturnStatus != 0) { Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus); return EFI_SUCCESS; } ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize; // // Get Data // ProfileBuffer = AllocateZeroPool (ProfileSize); if (ProfileBuffer == 0) { Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status); return Status; } CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET); CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET; CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData); CommGetProfileData->Header.ReturnStatus = (UINT64)-1; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Buffer = (UINT8 *) CommHeader + CommSize; Size -= CommSize; CommGetProfileData->ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) Buffer; CommGetProfileData->ProfileOffset = 0; while (CommGetProfileData->ProfileOffset < ProfileSize) { Offset = (UINTN) CommGetProfileData->ProfileOffset; if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) { CommGetProfileData->ProfileSize = (UINT64) Size; } else { CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset); } Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (CommGetProfileData->Header.ReturnStatus != 0) { FreePool (ProfileBuffer); Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus); return EFI_SUCCESS; } CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize); } Print (L"SmramProfileSize - 0x%x\n", ProfileSize); Print (L"======= SmramProfile begin =======\n"); DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize); Print (L"======= SmramProfile end =======\n\n\n"); FreePool (ProfileBuffer); return EFI_SUCCESS; }
/** Get and dump SMRAM profile data. @return EFI_SUCCESS Get the SMRAM profile data successfully. @return other Fail to get the SMRAM profile data. **/ EFI_STATUS GetSmramProfileData ( VOID ) { EFI_STATUS Status; UINTN CommSize; UINT8 *CommBuffer; EFI_SMM_COMMUNICATE_HEADER *CommHeader; SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo; SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *CommGetProfileData; UINT64 ProfileSize; PHYSICAL_ADDRESS ProfileBuffer; EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status)); return Status; } CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA); CommBuffer = AllocateZeroPool (CommSize); if (CommBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize, Status); return Status; } // // Get Size // CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO); CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO; CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo); CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1; CommGetProfileInfo->ProfileSize = 0; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); if (EFI_ERROR (Status)) { FreePool (CommBuffer); DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status)); return Status; } if (CommGetProfileInfo->Header.ReturnStatus != 0) { Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus); return EFI_SUCCESS; } ProfileSize = CommGetProfileInfo->ProfileSize; // // Get Data // ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool ((UINTN) ProfileSize); if (ProfileBuffer == 0) { FreePool (CommBuffer); Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN) ProfileSize, Status); return Status; } CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA); CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA; CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData); CommGetProfileData->Header.ReturnStatus = (UINT64)-1; CommGetProfileData->ProfileSize = ProfileSize; CommGetProfileData->ProfileBuffer = ProfileBuffer; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (CommGetProfileData->Header.ReturnStatus != 0) { FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer); FreePool (CommBuffer); Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus); return EFI_SUCCESS; } Print (L"SmramProfileSize - 0x%x\n", CommGetProfileData->ProfileSize); Print (L"======= SmramProfile begin =======\n"); DumpMemoryProfile (CommGetProfileData->ProfileBuffer, CommGetProfileData->ProfileSize); Print (L"======= SmramProfile end =======\n\n\n"); FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer); FreePool (CommBuffer); return EFI_SUCCESS; }